• R/O
  • HTTP
  • SSH
  • HTTPS

common_source_project-fm7: 提交

Common Source Code Project for Qt (a.k.a for FM-7).


Commit MetaInfo

修订版acabbae71fa23288634e7531a67acfc300016c5d (tree)
时间2019-02-12 07:48:32
作者K.Ohta <whatisthis.sowhat@gmai...>
CommiterK.Ohta

Log Message

[VM][PCENGINE][ADPCM] pce.cpp : porting logics from mednafen and Ootake.

更改概述

差异

--- a/source/src/vm/pcengine/adpcm.cpp
+++ b/source/src/vm/pcengine/adpcm.cpp
@@ -42,7 +42,7 @@ void ADPCM::initialize()
4242 reg_0c = 0;
4343 msm_last_cmd = 0;
4444 reg_0b = 0;
45- adpcm_volume = 0.0;
45+ adpcm_volume = 100.0;
4646
4747 memset(ram, 0x00, sizeof(ram));
4848 }
@@ -58,8 +58,11 @@ void ADPCM::reset()
5858 play_in_progress = false;
5959 adpcm_paused = false;
6060
61+ msm_data = 0x00;
6162 msm_ptr = 0;
6263 msm_nibble = 0;
64+ msm_length = 0;
65+
6366 adpcm_length = 0;
6467 addr_reg.w = 0;
6568 half_addr = 0;
@@ -110,7 +113,18 @@ uint32_t ADPCM::read_signal(int ch)
110113 return ((play_in_progress) ? 0xffffffff : 0);
111114 break;
112115 case SIG_ADPCM_STATUS_REG:
113- return reg_0c;
116+ {
117+ uint8_t data = reg_0c;
118+ // Hack from Ootake v2.83.
119+ if((play_in_progress)) {
120+ data = data & ~0x85;
121+ data = data | 0x08;
122+ } else {
123+ data = data | 0x01;
124+ data = data & ~0x0c;
125+ }
126+ return data;
127+ }
114128 break;
115129 case SIG_ADPCM_CMD_REG:
116130 return msm_last_cmd;
@@ -135,9 +149,10 @@ void ADPCM::reset_adpcm()
135149 out_debug_log(_T("RESET ADPCM\n"));
136150 d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff);
137151 d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff);
152+ msm_data = 0x00;
138153
139154 // stop ADPCM dma
140- //set_dma_status(false);
155+ set_dma_status(false);
141156 adpcm_repeat = false;
142157 //adpcm_stream = false;
143158 }
@@ -153,26 +168,22 @@ void ADPCM::do_play()
153168
154169 void ADPCM::do_pause(bool pause)
155170 {
156- if(!(play_in_progress)) return;
171+ //if(!(play_in_progress)) return;
157172 if(pause) {
158- if(!(adpcm_paused)) {
159- reg_0c |= ADPCM_STOP_FLAG;
160- reg_0c &= ~ADPCM_PLAY_FLAG;
161- msm_last_cmd &= ~0x60;
162- adpcm_paused = true;
163- d_msm->reset_w(1);
164- out_debug_log(_T("ADPCM PAUSE PLAY PTR=%04x\n"), msm_ptr);
165- touch_sound();
166- }
173+ reg_0c |= ADPCM_STOP_FLAG;
174+ reg_0c &= ~ADPCM_PLAY_FLAG;
175+ msm_last_cmd &= ~0x60;
176+ adpcm_paused = true;
177+ d_msm->reset_w(1);
178+ out_debug_log(_T("ADPCM PAUSE PLAY PTR=%04x\n"), msm_ptr);
179+ touch_sound();
167180 } else {
168- if((adpcm_paused)) {
169- adpcm_paused = false;
170- touch_sound();
171- reg_0c &= ~ADPCM_STOP_FLAG;
172- reg_0c |= ADPCM_PLAY_FLAG;
173- d_msm->reset_w(0);
174- out_debug_log(_T("ADPCM UNPAUSE PLAY PTR=%04x\n"), msm_ptr);
175- }
181+ adpcm_paused = false;
182+ touch_sound();
183+ reg_0c &= ~ADPCM_STOP_FLAG;
184+ reg_0c |= ADPCM_PLAY_FLAG;
185+ d_msm->reset_w(0);
186+ out_debug_log(_T("ADPCM UNPAUSE PLAY PTR=%04x\n"), msm_ptr);
176187 }
177188 }
178189
@@ -193,7 +204,7 @@ void ADPCM::do_stop(bool do_irq)
193204 void ADPCM::set_dma_status(bool flag)
194205 {
195206 dma_enabled = flag;
196- d_pce->write_signal(SIG_PCE_ADPCM_DMA, (flag) ? 0xffffffff : 0x00000000, 0xffffffff);
207+ //d_pce->write_signal(SIG_PCE_ADPCM_DMA, (flag) ? 0xffffffff : 0x00000000, 0xffffffff);
197208 }
198209
199210 void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask)
@@ -202,14 +213,14 @@ void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask)
202213 //if(ch != SIG_ADPCM_VCLK) out_debug_log(_T("WRITE_SIGNAL SIG=%d DATA=%04x MASK=%04x\n"), ch, data, mask);
203214 switch(ch) {
204215 case SIG_ADPCM_DMACTRL:
205- //if((reg_0b & 0x01) != (data & 0x01)) {
206- // set_dma_status((reg_0b & 0x01) != 0);
216+ if((data & 0x03) != 0) {
217+ set_dma_status(true);
207218 //reg_0b |= 0x02;
208- //}
219+ }
209220 reg_0b = data;
210221 break;
211222 case SIG_ADPCM_PAUSE:
212- do_pause(flag);
223+ //do_pause(flag);
213224 break;
214225 case SIG_ADPCM_DMA_ENABLED:
215226 set_dma_status(flag);
@@ -235,11 +246,12 @@ void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask)
235246 do_dma(data);
236247 break;
237248 case SIG_ADPCM_DO_DMA_TRANSFER:
238- if((play_in_progress) && ((write_ptr & 0xffff) >= (msm_ptr & 0xffff))) {
249+ if((play_in_progress) && !(adpcm_paused) && ((write_ptr & 0xffff) >= (msm_ptr & 0xffff))) {
239250 // now streaming, wait dma not to overwrite buffer before it is played
240- //reg_0b = 0x00;// From Ootake v2.38.
241- //set_dma_status(false);
251+ reg_0b = 0x00;// From Ootake v2.38.
252+ set_dma_status(false); // DON'T MODIFY PCE's DMA STATUS (HACK by K.O 20190212)
242253 } else {
254+ set_dma_status(true);
243255 do_dma(d_pce->read_signal(SIG_PCE_CDROM_RAW_DATA));
244256 }
245257 break;
@@ -250,6 +262,7 @@ void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask)
250262 addr_reg.b.h = data;
251263 if((msm_last_cmd & 0x10) != 0) {
252264 adpcm_length = (uint32_t)(addr_reg.w);
265+ msm_length = adpcm_length;
253266 out_debug_log(_T("SET ADDRESS REGISTER HIGH ; UPDATE LENGTH TO %04x\n"), adpcm_length);
254267 }
255268 break;
@@ -260,6 +273,7 @@ void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask)
260273 addr_reg.b.l = data;
261274 if((msm_last_cmd & 0x10) != 0) {
262275 adpcm_length = (uint32_t)(addr_reg.w);
276+ msm_length = adpcm_length;
263277 out_debug_log(_T("SET ADDRESS REGISTER LOW ; UPDATE LENGTH TO %04x\n"), adpcm_length);
264278 }
265279 break;
@@ -290,6 +304,10 @@ void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask)
290304 adpcm_clock_divider = 0x10 - (data & 0x0f);
291305 d_msm->change_clock_w((ADPCM_CLOCK / 6) / adpcm_clock_divider);
292306 break;
307+ case SIG_ADPCM_CLEAR_ACK:
308+ reg_0b &= 0xfc; // Clear status register.
309+ dma_enabled = false;
310+ break;
293311 }
294312 }
295313
@@ -300,56 +318,20 @@ void ADPCM::do_cmd(uint8_t cmd)
300318 if(((cmd & 0x80) != 0) /*&& ((msm_last_cmd & 0x80) == 0)*/) {
301319 // Reset ADPCM
302320 reset_adpcm();
303- msm_init(); // SAMPLE = 0x800, SSI=0
321+ msm_init(); // SAMPLE = 0x800, SSIS=0
304322 out_debug_log(_T("ADPCM CMD RESET\n"));
305323 msm_last_cmd = cmd;
306324 return;
307325 }
308- bool req_play = false;
309- bool req_play_0 = ((cmd & 0x40) != 0) ? true : false;
310- adpcm_repeat = ((cmd & 0x20) != 0) ? true : false;
311- uint32_t _clk = (ADPCM_CLOCK / 6) / adpcm_clock_divider;
312-
313- if((play_in_progress) && !(adpcm_repeat)) {
314- req_play = false;
315- }
316- if(!(play_in_progress) && (adpcm_repeat)) {
317- d_msm->change_clock_w((ADPCM_CLOCK / 6) / adpcm_clock_divider); // From mednafen 1.22.1
318- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff);
319- req_play = true;
320- msm_nibble = 0;
321- msm_init(); // SAMPLE = 0x800, SSI=0
322- }
323- //if(req_play_0) {
324- // req_play = true;
325- //} else {
326- // if(/*(play_in_progress) && */(written_size > 0x8000)) {
327- // req_play = true;
328- // }
329- //}
330- if(((cmd & 0x10) != 0) /*&& ((msm_last_cmd & 0x10) == 0)*/){
331- // ADPCM set length
332- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff);
333- //adpcm_stopped = false;
334- adpcm_length = (uint32_t)(addr_reg.w);
335- out_debug_log(_T("ADPCM SET LENGTH TO %04x\n"), adpcm_length);
336- }
337326
338- if(((cmd & 0x08) != 0) /*&& ((msm_last_cmd & 0x08) == 0)*/) {
339- // ADPCM set read address
340- read_ptr = (uint32_t)(addr_reg.w);
341- read_buf = ((cmd & 0x04) == 0) ? 2 : 1;
342- read_ptr = ((cmd & 0x04) == 0) ? ((read_ptr - 1) & 0xffff) : read_ptr;
343- msm_ptr = read_ptr;
344- out_debug_log(_T("ADPCM SET READ ADDRESS ADDR=%04x BUF=%01x \n"), read_ptr, read_buf);
345- }
346327 if(((cmd & 0x02) != 0) /*&& ((msm_last_cmd & 0x02) == 0)*/) {
347328 // ADPCM set write address
348329 write_ptr = (uint32_t)(addr_reg.w);
349330 write_buf = ((cmd & 0x01) == 0) ? 1 : 0;
350- //written_size = 0;
351- write_ptr = (write_ptr - write_buf) & 0xffff;
331+ written_size = 0; // OK?
332+ //write_ptr = (write_ptr - write_buf) & 0xffff;
352333 // It's ugly... (;_;)
334+ uint32_t _clk = (ADPCM_CLOCK / 6) / adpcm_clock_divider;
353335 if(((read_ptr & 0xffff) >= 0x4000) &&
354336 ((write_ptr & 0xffff) == 0x0000) &&
355337 (adpcm_length != 0x8000) &&
@@ -357,11 +339,76 @@ void ADPCM::do_cmd(uint8_t cmd)
357339 (_clk < 16000)) {
358340 adpcm_length = adpcm_length & 0x7fff;
359341 }
342+ msm_length = adpcm_length;
360343 out_debug_log(_T("ADPCM SET WRITE ADDRESS ADDR=%04x BUF=%01x \n"), write_ptr, write_buf);
361344 }
345+ if(((cmd & 0x08) != 0) /*&& ((msm_last_cmd & 0x08) == 0)*/) {
346+ // ADPCM set read address
347+ read_ptr = (uint32_t)(addr_reg.w);
348+ read_buf = ((cmd & 0x04) == 0) ? 2 : 1;
349+ //read_ptr = ((cmd & 0x04) == 0) ? ((read_ptr - 1) & 0xffff) : read_ptr;
350+ msm_ptr = read_ptr;
351+ out_debug_log(_T("ADPCM SET READ ADDRESS ADDR=%04x BUF=%01x \n"), read_ptr, read_buf);
352+ }
353+ if(((cmd & 0x10) != 0) /*&& ((msm_last_cmd & 0x10) == 0)*/){
354+ // ADPCM set length
355+ //d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff);
356+ adpcm_stopped = false;
357+ adpcm_length = (uint32_t)(addr_reg.w);
358+ msm_length = adpcm_length;
359+ out_debug_log(_T("ADPCM SET LENGTH TO %04x\n"), adpcm_length);
360+ }
361+ bool req_play = false;
362+ bool req_play_0 = ((cmd & 0x40) != 0) ? true : false;
363+ adpcm_repeat = ((cmd & 0x20) != 0) ? true : false;
364+
365+ if((play_in_progress) && !(adpcm_paused) && !(adpcm_repeat)) {
366+ req_play = false;
367+ }
368+ if(!(play_in_progress) && !(adpcm_paused) && (adpcm_repeat)) {
369+ d_msm->change_clock_w((ADPCM_CLOCK / 6) / adpcm_clock_divider); // From mednafen 1.22.1
370+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff);
371+ req_play = true;
372+ msm_nibble = 0;
373+ msm_init(); // SAMPLE = 0x800, SSI=0
374+ }
375+#if 1
376+ if((play_in_progress) && !(adpcm_paused)) {
377+ if(req_play) { // Update only
378+ msm_ptr = read_ptr & 0xffff;
379+ msm_nibble = 0;
380+ if(((adpcm_length & 0xffff) >= 0x8000) && ((adpcm_length & 0xffff) <= 0x80ff)) {
381+ half_addr = (read_ptr + 0x85) & 0xffff;
382+ } else {
383+ half_addr = (read_ptr + (adpcm_length >> 1)) & 0xffff;
384+ }
385+ //do_pause(false);
386+ //
387+ } else {
388+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff);
389+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
390+ adpcm_stream = false;
391+ adpcm_repeat = false;
392+ }
393+ } else { // Not playing
394+ if(req_play) {
395+ msm_ptr = read_ptr & 0xffff;
396+ half_addr = (msm_ptr + (adpcm_length / 2)) & 0xffff;
397+ write_ptr &= 0xffff;
398+ msm_nibble = 0;
399+ do_play();
400+ d_msm->reset_w(0);
401+ } else {
402+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff);
403+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
404+ adpcm_stream = false;
405+ adpcm_repeat = false;
406+ }
407+ }
408+#else
362409 if((req_play) && !(play_in_progress)) {
363410 msm_ptr = read_ptr & 0xffff;
364- half_addr = (msm_ptr + (adpcm_length / 2)) & 0xffff;
411+ half_addr = (msm_ptr + ((adpcm_length + 1) / 2)) & 0xffff;
365412 if(((adpcm_length & 0xffff) >= 0x8000) && ((adpcm_length & 0xffff) <= 0x80ff)) {
366413 half_addr = (read_ptr + 0x85) & 0xffff;
367414 }
@@ -370,15 +417,17 @@ void ADPCM::do_cmd(uint8_t cmd)
370417 d_msm->reset_w(0);
371418 out_debug_log(_T("ADPCM START PLAY(%s) START=%04x LENGTH=%04x HALF=%04x\n"), (dma_enabled) ? _T("DMA") : _T("PIO"), msm_ptr, adpcm_length, half_addr);
372419 } else if((req_play) /*&& (cmd != msm_last_cmd)*/){
373- if(((adpcm_length & 0xffff) >= 0x8000) && ((adpcm_length & 0xffff) <= 0x80ff)) {
420+ msm_ptr = read_ptr & 0xffff;
421+ half_addr = (msm_ptr + (adpcm_length / 2)) & 0xffff;
422+ if(((adpcm_length & 0xffff) >= 0x8000) && ((adpcm_length & 0xffff) <= 0x80ff)) {
374423 half_addr = (read_ptr + 0x85) & 0xffff;
375424 } else {
376425 half_addr = (read_ptr + (adpcm_length >> 1)) & 0xffff;
377426 }
378427 out_debug_log(_T("ADPCM UPDATE HALF ADDRESS HALF=%04x LENGTH=%04x\n"), half_addr, adpcm_length);
379428 } else /*if(cmd != msm_last_cmd)*/ { // !req_play
380- //msm_nibble = 0;
381- if(play_in_progress) {
429+ adpcm_repeat = false;
430+ if(play_in_progress && !(adpcm_paused)) {
382431 //adpcm_stopped = true;
383432 //play_in_progress = false;
384433 //d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff);
@@ -396,6 +445,7 @@ void ADPCM::do_cmd(uint8_t cmd)
396445 // do_stop(false);
397446 // d_msm->reset_w(1);
398447 //}
448+#endif
399449 msm_last_cmd = cmd;
400450
401451 }
@@ -410,119 +460,119 @@ void ADPCM::msm_init()
410460 void ADPCM::do_vclk(bool flag)
411461 {
412462 if((flag)) {
413- uint8_t msm_data;
414463 {
415- if(!(adpcm_stopped)) {
416- msm_data = (msm_nibble != 0) ? (ram[msm_ptr & 0xffff] & 0x0f) : ((ram[msm_ptr & 0xffff] & 0xf0) >> 4);
417- if(play_in_progress) {
418- d_msm->data_w(msm_data);
464+ if((play_in_progress) && !(adpcm_paused) && (adpcm_length > 0)) {
465+ if(!((adpcm_length == 1) && ((msm_nibble & 1) == 0))) {
466+ msm_data = (msm_nibble != 0) ? (ram[msm_ptr & 0xffff] & 0x0f) : ((ram[msm_ptr & 0xffff] & 0xf0) >> 4);
419467 }
468+ d_msm->data_w(msm_data);
420469 msm_nibble ^= 1;
421470 }
422- if(msm_nibble == 0) {
423- if((written_size > 0) && !(adpcm_stopped)) written_size--;
471+ if((msm_nibble == 0) && (play_in_progress) && !(adpcm_paused)) {
472+ if((written_size > 0) /*&& !(adpcm_stopped)*/) written_size--;
424473 // Increment pointers.
425- if((adpcm_length == 0) && ((msm_last_cmd & 0x10) == 0)) {
426- if(!(adpcm_stopped)) {
427- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
428- if((msm_last_cmd & 0x40) != 0) {
429- do_stop(false);
430- d_msm->reset_w(1);
474+#if 0
475+ if((adpcm_length == 0) && ((msm_last_cmd & 0x10) == 0)){
476+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
477+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff);
478+ if((msm_last_cmd & 0x40) != 0) {
479+ do_stop(false);
480+ d_msm->reset_w(1);
481+ }
482+ adpcm_repeat = false;
483+ adpcm_stream = false;
484+ } else {
485+ if(adpcm_length > 0) adpcm_length--;
486+ msm_ptr = (msm_ptr + 1) & 0xffff;
487+ read_ptr = msm_ptr;
488+ if((adpcm_repeat) && (msm_length >= 0x8000) && (msm_length <= 0x80ff)) {
489+ if(msm_ptr == (half_addr & 0xffff)) {
490+ half_addr = (half_addr + 0x85) & 0xffff;
491+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff);
492+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
493+ }
494+ //out_debug_log(_T("PLAY PASSED TO THE HALF ADDR=%08x SIZE=%04x LENGTH=%04x\n"), msm_ptr, written_size, msm_length);
495+ } else if(msm_length < 0x7fff) {
496+ if(msm_ptr == (half_addr & 0xffff)) {
497+ half_addr = (half_addr + (msm_length & 0xffff) - 1024) & 0xffff;
498+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff);
499+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
431500 }
432- out_debug_log(_T("PLAY REACHED TO THE END ADDR=%08x SIZE=%04x LENGTH=%04x\n"), msm_ptr, written_size, adpcm_length);
433- adpcm_stopped = true;
501+ //out_debug_log(_T("PLAY PASSED TO THE HALF ADDR=%08x SIZE=%04x LENGTH=%04x\n"), msm_ptr, written_size, msm_length);
434502 } else {
435- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x0, 0xffffffff);
503+ if((msm_ptr == 0x8000) || (msm_ptr == 0x0000)) {
504+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff);
505+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
506+ }
507+ }
508+ }
509+
510+#else
511+ if((adpcm_length == 0)) {
512+ if((msm_last_cmd & 0x10) == 0) {
513+ if(!(adpcm_stopped)) {
514+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x0, 0xffffffff);
515+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
516+ if((msm_last_cmd & 0x40) != 0) {
517+ do_stop(false);
518+ d_msm->reset_w(1);
519+ }
520+ out_debug_log(_T("PLAY REACHED TO THE END ADDR=%08x SIZE=%04x LENGTH=%04x\n"), msm_ptr, written_size, adpcm_length);
521+ adpcm_stopped = true;
522+ } else {
523+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x0, 0xffffffff);
524+ }
436525 }
437526 } else if((msm_ptr & 0xffff) == (half_addr & 0xffff)) {
438- if(!(adpcm_stopped)) {
527+ //if(!(adpcm_stopped)) {
528+ if((msm_last_cmd & 0x10) == 0) {
439529 d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
530+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x0, 0xffffffff);
440531 out_debug_log(_T("PLAY PASSED TO THE HALF ADDR=%08x SIZE=%04x LENGTH=%04x\n"), msm_ptr, written_size, adpcm_length);
441532 }
533+ //}
442534 }
443-#if 0
535+#if 1
444536 else if((!((dma_enabled) && (adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff)) &&
445537 !(adpcm_length < 0x7fff)) &&
446538 (((msm_ptr & 0xffff) == 0x8000) || ((msm_ptr & 0xffff) == 0x0000))) {
447539 // 20181213 K.O: Porting from Ootake v2.83.Thanks to developers of Ootake.
448540 //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
449- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
450-
541+ if((msm_last_cmd & 0x10) == 0) {
542+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
543+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x0, 0xffffffff);
544+ }
451545 out_debug_log(_T("SPECIAL HALF ADDRESS MSM_ADDR=%08x\n"), msm_ptr);
452546 }
453547 #endif
454548 if(!(adpcm_stopped)) {
455549 msm_ptr = (msm_ptr + 1) & 0xffff;
456- //read_ptr = msm_ptr;
550+ read_ptr = msm_ptr;
457551 }
458552 if((msm_last_cmd & 0x10) == 0) {
459553 if(adpcm_length > 0) {
460554 adpcm_length--;
461555 } else {
462556 if(!(adpcm_stopped)) {
463- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x0, 0xffffffff);
464- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
465- if((msm_last_cmd & 0x40) != 0) {
466- do_stop(false);
467- }
468- out_debug_log(_T("PLAY REACHED TO THE END2 ADDR=%08x SIZE=%04x LENGTH=%04x\n"), msm_ptr, written_size, adpcm_length);
557+ if((msm_last_cmd & 0x10) == 0) {
558+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x0, 0xffffffff);
559+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
560+ if((msm_last_cmd & 0x40) != 0) {
561+ do_stop(false);
562+ }
563+ out_debug_log(_T("PLAY REACHED TO THE END2 ADDR=%08x SIZE=%04x LENGTH=%04x\n"), msm_ptr, written_size, adpcm_length);
469564 adpcm_stopped = true;
565+ }
470566 }
471567 }
472568 }
473-#if 0
474- if((adpcm_repeat) && (dma_enabled) &&
475- (adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff) /* && (IsHuVideo()) */) {
476- written_size++;
477- msm_ptr = (msm_ptr - 1) & 0xffff;
478- goto __skip1;
479- }
480-
481- if(adpcm_length > 0) adpcm_length--;
482- if(written_size > 0) written_size--;
483- if((dma_enabled) && (written_size < 0xffff)) {
484- if(d_pce->read_signal(SIG_PCE_CDROM_DATA_IN) != 0) {
485- do_dma(d_pce->read_signal(SIG_PCE_CDROM_RAW_DATA));
486- }
487- }
488- if(adpcm_length == 0) {
489- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x0, 0xffffffff);
490- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
491- adpcm_stopped = true;
492- out_debug_log(_T("PLAY PASSED TO THE FULL ADDR=%08x SIZE=%04x\n"), msm_ptr, written_size);
493- do_stop(false);
494- } else if((msm_ptr & 0xffff) == half_addr) {
495- // 20181213 K.O: Porting from Ootake v2.83.Thanks to developers of Ootake.
496- if((dma_enabled) && (adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff)) {
497- half_addr = (half_addr + 0x85) & 0xffff;
498- } else if(adpcm_length < 0x7fff) {
499- half_addr = (half_addr + (uint16_t)(adpcm_length - 1024)) & 0xffff;
500- }
501- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
502- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff);
503- out_debug_log(_T("PLAY PASSED TO THE HALF ADDR=%08x SIZE=%04x\n"), msm_ptr, written_size);
504- } /*else if((msm_ptr & 0xffff) == ((half_addr + 1) & 0xffff)) {
505- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff);
506- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff);
507- } */else if((!((dma_enabled) && (adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff)) &&
508- !(adpcm_length < 0x7fff))) {
509- if(((msm_ptr & 0xffff) == 0x8000) || ((msm_ptr & 0xffff) == 0x0000)) {
510- // 20181213 K.O: Porting from Ootake v2.83.Thanks to developers of Ootake.
511- //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
512- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff);
513- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
514- adpcm_stopped = false;
515- out_debug_log(_T("SPECIAL HALF ADDRESS MSM_ADDR=%08x\n"), msm_ptr);
516- } else if(((msm_ptr & 0xffff) == 0x8001) || ((msm_ptr & 0xffff) == 0x0001)) {
517- //d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x0, 0xffffffff);
518- }
519- }
520- msm_ptr++;
521569 #endif
570+
522571 #if 1
523572 __skip1:
524- if((dma_enabled) && (written_size <= 0)) {
573+ if((dma_enabled) /*&& (written_size <= 0) && !(adpcm_stopped)*/) {
525574 if(d_pce->read_signal(SIG_PCE_CDROM_DATA_IN) != 0) {
575+ //do_pause(false); // Unpause if paused && data in.
526576 do_dma(d_pce->read_signal(SIG_PCE_CDROM_RAW_DATA));
527577 }
528578 } else {
@@ -539,7 +589,7 @@ bool ADPCM::do_dma(uint8_t data)
539589 {
540590 ram[write_ptr & 0xffff] = data;
541591 write_ptr = (write_ptr + 1) & 0xffff;
542- written_size++;
592+ written_size = (written_size + 1) & 0xffff;;
543593 //set_ack(0);
544594
545595 reg_0c &= ~ADPCM_REMAIN_WRITE_BUF;
@@ -648,8 +698,10 @@ bool ADPCM::process_state(FILEIO* state_fio, bool loading)
648698 state_fio->StateValue(write_ptr);
649699 state_fio->StateValue(write_buf);
650700
701+ state_fio->StateValue(msm_data);
651702 state_fio->StateValue(msm_ptr);
652703 state_fio->StateValue(msm_nibble);
704+ state_fio->StateValue(msm_length);
653705 state_fio->StateValue(half_addr);
654706 state_fio->StateValue(adpcm_length);
655707
--- a/source/src/vm/pcengine/adpcm.h
+++ b/source/src/vm/pcengine/adpcm.h
@@ -37,6 +37,7 @@
3737 #define SIG_ADPCM_ADDR_LO 14
3838 #define SIG_ADPCM_SET_DIVIDER 15
3939 #define SIG_ADPCM_CMD_REG 16
40+#define SIG_ADPCM_CLEAR_ACK 17
4041
4142 class MSM5205;
4243
@@ -54,9 +55,11 @@ protected:
5455 uint32_t write_ptr;
5556 uint32_t read_buf;
5657 uint32_t write_buf;
57-
58+
59+ uint8_t msm_data;
5860 uint32_t msm_ptr;
5961 uint32_t msm_nibble;
62+ uint32_t msm_length;
6063 uint32_t half_addr;
6164 uint32_t adpcm_length;
6265 bool adpcm_stream;
--- a/source/src/vm/pcengine/pce.cpp
+++ b/source/src/vm/pcengine/pce.cpp
@@ -1866,8 +1866,11 @@ void PCE::cdrom_reset()
18661866 adpcm_read_buf = adpcm_write_buf = 0;
18671867 adpcm_dma_enabled = false;
18681868 adpcm_play_in_progress = false;
1869+ adpcm_written = 0;
18691870 msm_idle = 1;
1870-
1871+ #ifdef USE_SEPARATED_ADPCM
1872+ d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, 0x00, 0x03);
1873+ #endif
18711874 if(event_cdda_fader != -1) {
18721875 cancel_event(this, event_cdda_fader);
18731876 }
@@ -1894,6 +1897,7 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data)
18941897 d_scsi_host->write_signal(SIG_SCSI_SEL, 1, 1);
18951898 d_scsi_host->write_signal(SIG_SCSI_SEL, 0, 1);
18961899 #ifdef USE_SEPARATED_ADPCM
1900+ adpcm_dma_enabled = false;
18971901 d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, 0x00, 0xff);
18981902 #else
18991903 adpcm_dma_enabled = false;
@@ -1936,7 +1940,7 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data)
19361940 // Reset ADPCM hardware
19371941 #ifdef USE_SEPARATED_ADPCM
19381942 d_adpcm->write_signal(SIG_ADPCM_RESET, 0xff, 0xff);
1939- d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, 0x00, 0xff);
1943+ adpcm_dma_enabled = false;
19401944 #else
19411945 reset_adpcm();
19421946 adpcm_dma_enabled = false;
@@ -1962,11 +1966,15 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data)
19621966 #ifdef USE_SEPARATED_ADPCM
19631967 d_adpcm->write_signal(SIG_ADPCM_ADDR_LO, data, 0xff);
19641968 #endif
1969+ //cdrom_regs[addr & 0x0f] = data;
1970+ //adpcm_length = (cdrom_regs[0x09] << 8) | cdrom_regs[0x08];
19651971 break;
19661972 case 0x09: /* ADPCM address (MSB) */
19671973 #ifdef USE_SEPARATED_ADPCM
19681974 d_adpcm->write_signal(SIG_ADPCM_ADDR_HI, data, 0xff);
19691975 #endif
1976+ //cdrom_regs[addr & 0x0f] = data;
1977+ //adpcm_length = (cdrom_regs[0x09] << 8) | cdrom_regs[0x08];
19701978 break;
19711979
19721980 case 0x0a: /* ADPCM RAM data port */
@@ -1985,12 +1993,11 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data)
19851993 #ifdef USE_SEPARATED_ADPCM
19861994 d_adpcm->write_signal(SIG_ADPCM_DMACTRL, data, 0xff);
19871995 #endif
1988- if(data & 3) {
1996+ if((data & 3) != 0) {
19891997 /* Start CD to ADPCM transfer */
19901998 adpcm_dma_enabled = true;
19911999 #ifdef USE_SEPARATED_ADPCM
19922000 d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, 0xffffffff, 0xffffffff);
1993- data = d_adpcm->read_signal(SIG_ADPCM_DMACTRL);
19942001 #else
19952002 cdrom_regs[0x0c] |= 0x04;
19962003 if(d_scsi_cdrom->get_cur_command() == SCSI_CMD_READ6 &&
@@ -2028,40 +2035,45 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data)
20282035 // Reset ADPCM hardware
20292036 reset_adpcm();
20302037 adpcm_stop(true);
2038+ adpcm_dma_enabled = false;
20312039 out_debug_log(_T("ADPCM CMD=$0D RESET\n"));
20322040 }
20332041
2034- if(data & 0x08) {
2042+ if(((data & 0x08) != 0) && ((reg_bak & 0x08) == 0)) {
20352043 // ADPCM set read address
20362044 adpcm_read_ptr = (cdrom_regs[0x09] << 8) | cdrom_regs[0x08];
20372045 adpcm_read_buf = ((data & 0x04) == 0) ? 2 : 1;
20382046 out_debug_log(_T("ADPCM SET READ ADDRESS ADDR=%04x\n"), adpcm_read_ptr);
2047+ msm_start_addr = (adpcm_read_ptr) & 0xffff;
2048+ if((data & 0x04) == 0) {
2049+ msm_start_addr = (msm_start_addr - 1) & 0xffff;
2050+ }
20392051 }
20402052 if(data & 0x10) {
20412053 // ADPCM set length
20422054 adpcm_length = (cdrom_regs[0x09] << 8) | cdrom_regs[0x08];
20432055 }
20442056 uint32_t _clk = (ADPCM_CLOCK / 6) / adpcm_clock_divider;
2045- if(data & 0x02) {
2057+ if(((data & 0x02) != 0) && ((reg_bak & 0x02) == 0)) {
20462058 // ADPCM set write address
20472059 adpcm_write_ptr = (cdrom_regs[0x09] << 8) | cdrom_regs[0x08];
20482060 adpcm_write_buf = ((data & 1) == 0) ? 1 : 0;
2049- adpcm_written = 0;
2061+ //adpcm_written = 0;
20502062 // It's ugly... (;_;)
2051- if(((adpcm_read_ptr & 0xffff) >= 0x4000) &&
2052- ((adpcm_write_ptr & 0xffff) == 0x0000) &&
2053- (adpcm_length != 0x8000) &&
2054- (adpcm_length != 0xffff) &&
2055- (_clk < 16000)) {
2056- adpcm_length = adpcm_length & 0x7fff;
2057- }
2063+ //if(((adpcm_read_ptr & 0xffff) >= 0x4000) &&
2064+ // ((adpcm_write_ptr & 0xffff) == 0x0000) &&
2065+ // (adpcm_length != 0x8000) &&
2066+ // (adpcm_length != 0xffff) &&
2067+ // (_clk < 16000)) {
2068+ // adpcm_length = adpcm_length & 0x7fff;
2069+ //}
20582070 if((adpcm_write_ptr == 0) || (adpcm_write_ptr == 0x8000) || ((adpcm_write_ptr & 0x1fff) == 0x1fff)) {
20592071 if((((adpcm_read_ptr + adpcm_length) & 0x1fff) == 0x1fff) ||
20602072 ((adpcm_read_ptr == 0) && (adpcm_length == 0x8000))) {
20612073 adpcm_stream = true;
20622074 }
20632075 }
2064- out_debug_log(_T("ADPCM SET WRITE ADDRESS ADDR=%04x\n"), adpcm_write_ptr);
2076+ out_debug_log(_T("ADPCM SET WRITE ADDRESS ADDR=%04x STREAM=%s\n"), adpcm_write_ptr, (adpcm_stream) ? _T("YES") : _T("NO"));
20652077 }
20662078 if(data & 0x10) {
20672079 if(((adpcm_read_ptr & 0xffff) >= 0x4000) &&
@@ -2073,7 +2085,8 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data)
20732085 }
20742086 out_debug_log(_T("ADPCM SET LENGTH LENGTH=%04x\n"), adpcm_length);
20752087 }
2076- bool req_play = false;
2088+ bool req_play = adpcm_play_in_progress;
2089+ //bool req_play = false;
20772090 {
20782091 adpcm_repeat = ((data & 0x20) != 0) ? true : false;
20792092 if((adpcm_play_in_progress) && !(adpcm_repeat) && !(adpcm_stream)) {
@@ -2083,22 +2096,27 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data)
20832096 req_play = true;
20842097 }
20852098 }
2086- if((data & 0x40) != 0) req_play = true;
2087- if((data & 0x40) == 0) {
2088- if((adpcm_stream) && (adpcm_written > 0x8000)) {
2089- req_play = true;
2099+ if((data & 0x40) != 0) {
2100+ req_play = true;
2101+ } else {
2102+ if(adpcm_stream) {
2103+ if(adpcm_written > 0x8000) {
2104+ req_play = false;
2105+ } else {
2106+ cdrom_regs[addr & 0x0f] = data;
2107+ return; // Exit from command. 20190212 K.O
2108+ }
20902109 }
20912110 }
20922111
2093- bool _play = adpcm_play_in_progress;
20942112 if(req_play) {
2095- msm_start_addr = (adpcm_read_ptr) & 0xffff;
2096- if(/*((data & 0x40) != 0) && */!(adpcm_play_in_progress)) {
2113+// msm_start_addr = (adpcm_read_ptr) & 0xffff;
2114+ if(((data & 0x40) != 0) /*&& !(adpcm_play_in_progress)*/) {
20972115 // ADPCM play
2098- msm_start_addr = (adpcm_read_ptr) & 0xffff;
20992116 msm_end_addr = (adpcm_read_ptr + adpcm_length) & 0xffff;
2100- msm_half_addr = (adpcm_read_ptr + (adpcm_length / 2)) & 0xffff;
2117+ msm_half_addr = (adpcm_read_ptr + ((adpcm_length + 1) >> 1)) & 0xffff;
21012118 adpcm_write_ptr &= 0xffff;
2119+ //adpcm_written = 0; // OK?
21022120 msm_nibble = 0;
21032121 adpcm_play_in_progress = true;
21042122 adpcm_play();
@@ -2109,34 +2127,18 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data)
21092127 if(((adpcm_length & 0xffff) >= 0x8000) && ((adpcm_length & 0xffff) <= 0x80ff)) {
21102128 msm_half_addr = (adpcm_read_ptr + 0x85) & 0xffff;
21112129 } else {
2112- msm_half_addr = (adpcm_read_ptr + (adpcm_length >> 1)) & 0xffff;
2130+ msm_half_addr = (adpcm_read_ptr + ((adpcm_length + 1) >> 1)) & 0xffff;
21132131 }
21142132 out_debug_log(_T("ADPCM UPDATE HALF ADDRESS HALF=%04x\n"), msm_half_addr);
2115- adpcm_pause(false);
21162133 }
21172134
21182135 } else {
2119-
2136+ //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE);
2137+ // set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE);
21202138 adpcm_stream = false;
21212139 adpcm_repeat = false;
2122- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE);
2123- out_debug_log(_T("ADPCM STATUS UPDATE PLAY=%s\n"), (adpcm_play_in_progress) ? _T("YES") : _T("NO")); //if(adpcm_play_in_progress) {
2124- // adpcm_stop(true);
2125- // d_msm->reset_w(1);
2126- //} else {
2127- //adpcm_pause(true);
2128- //d_msm->reset_w(1);
2129- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE);
2130- //}
2140+ out_debug_log(_T("ADPCM STATUS UPDATE PLAY=%s\n"), (adpcm_play_in_progress) ? _T("YES") : _T("NO")); adpcm_stop(false);
21312141 }
2132- // used by Buster Bros to cancel an in-flight sample
2133- // if repeat flag (bit5) is high, ADPCM should be fully played (from Ootake)
2134- /*if(!(data & 0x20)) {
2135- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE);
2136- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
2137- adpcm_stop(false);
2138- d_msm->reset_w(1);
2139- }*/
21402142 }
21412143 #endif
21422144 break;
@@ -2376,9 +2378,9 @@ uint8_t PCE::cdrom_read(uint16_t addr)
23762378 break;
23772379
23782380 case 0x0b: /* ADPCM DMA control */
2379- //#ifdef USE_SEPARATED_ADPCM
2380- //data = d_adpcm->read_signal(SIG_ADPCM_DMACTRL);
2381- //#endif
2381+ #ifdef USE_SEPARATED_ADPCM
2382+ data = d_adpcm->read_signal(SIG_ADPCM_DMACTRL);
2383+ #endif
23822384 break;
23832385
23842386 case 0x0c: /* ADPCM status */
@@ -2434,6 +2436,7 @@ void PCE::reset_adpcm()
24342436
24352437 // stop ADPCM dma
24362438 adpcm_dma_enabled = false;
2439+ adpcm_written = 0;
24372440 adpcm_repeat = false;
24382441 adpcm_stream = false;
24392442 }
@@ -2441,13 +2444,13 @@ void PCE::reset_adpcm()
24412444 void PCE::write_adpcm_ram(uint8_t data)
24422445 {
24432446 adpcm_ram[(adpcm_write_ptr++) & 0xffff] = data;
2444-// adpcm_write_ptr = adpcm_write_ptr & 0xffff;
2447+ adpcm_write_ptr = adpcm_write_ptr & 0xffff;
24452448 }
24462449
24472450 uint8_t PCE::read_adpcm_ram()
24482451 {
24492452 uint8_t _data = adpcm_ram[(adpcm_read_ptr++) & 0xffff];
2450-// adpcm_read_ptr = adpcm_read_ptr & 0xffff;
2453+ adpcm_read_ptr = adpcm_read_ptr & 0xffff;
24512454 return _data;
24522455 }
24532456
@@ -2465,11 +2468,9 @@ void PCE::adpcm_play()
24652468 cdrom_regs[0x0c] &= ~PCE_CD_ADPCM_STOP_FLAG;
24662469 cdrom_regs[0x0c] |= PCE_CD_ADPCM_PLAY_FLAG;
24672470 set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
2468- //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE);
2471+ set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE);
24692472 cdrom_regs[0x03] &= ~(PCE_CD_IRQ_SAMPLE_FULL_PLAY | PCE_CD_IRQ_SAMPLE_HALF_PLAY);
2470- //set_cdrom_irq_line((PCE_CD_IRQ_SAMPLE_FULL_PLAY | PCE_CD_IRQ_SAMPLE_HALF_PLAY), CLEAR_LINE);
2471- //msm_end_addr = (msm_end_addr & 0xffff) + 1; // 20190209 K.O from Ootake.
2472- //msm_start_addr = msm_start_addr & 0xffff;
2473+ msm_start_addr = msm_start_addr & 0xffff;
24732474 msm_idle = 0;
24742475 }
24752476
@@ -2528,11 +2529,11 @@ void PCE::clear_ack()
25282529 {
25292530 cdrom_regs[0x03] &= ~0x40; // From Ootake v2.38
25302531 if(d_scsi_host->read_signal(SIG_SCSI_CD) != 0) {
2531- //cdrom_regs[0x0b] &= 0xfc;
2532- cdrom_regs[0x0b] &= ~1;
25332532 #ifdef USE_SEPARATED_ADPCM
2534- d_adpcm->write_signal(SIG_ADPCM_DMACTRL, cdrom_regs[0x0b], 0xff);
2535- d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, cdrom_regs[0x0b], 0x03);
2533+ d_adpcm->write_signal(SIG_ADPCM_CLEAR_ACK, 0xff, 0xff);
2534+ #else
2535+ cdrom_regs[0x0b] &= 0xfc;
2536+ //cdrom_regs[0x0b] &= ~1;
25362537 #endif
25372538 }
25382539 d_scsi_host->write_signal(SIG_SCSI_ACK, 0, 0);
@@ -2540,6 +2541,9 @@ void PCE::clear_ack()
25402541
25412542 void PCE::set_cdrom_irq_line(int num, int state)
25422543 {
2544+ if(((num & PCE_CD_IRQ_SAMPLE_FULL_PLAY) != 0) || ((num & PCE_CD_IRQ_SAMPLE_HALF_PLAY) != 0)) { // 20190212 K.O from mednafen.
2545+ cdrom_regs[0x03] &= ~(PCE_CD_IRQ_SAMPLE_FULL_PLAY | PCE_CD_IRQ_SAMPLE_HALF_PLAY);
2546+ }
25432547 if (state == ASSERT_LINE) {
25442548 cdrom_regs[0x03] |= num;
25452549 } else {
@@ -2654,15 +2658,14 @@ void PCE::write_signal(int id, uint32_t data, uint32_t mask)
26542658 //out_debug_log(_T("CDROM DRQ(ADPCM)\n"));
26552659 #ifdef USE_SEPARATED_ADPCM
26562660 if(adpcm_dma_enabled) {
2657- d_adpcm->write_signal(SIG_ADPCM_DMACTRL, cdrom_regs[0x0b], 0xff);
26582661 d_adpcm->write_signal(SIG_ADPCM_DO_DMA_TRANSFER, 0xff, 0xff);
2659- cdrom_regs[0x0b] = d_adpcm->read_signal(SIG_ADPCM_DMACTRL);
26602662 }
26612663 #else
26622664 if(adpcm_dma_enabled) {
2663- if(!(msm_idle) && ((adpcm_write_ptr & 0xffff) >= (msm_start_addr & 0xffff))) {
2665+ if(!(msm_idle) && ((adpcm_write_ptr & 0xffff) < (msm_start_addr & 0xffff))) {
26642666 // now streaming, wait dma not to overwrite buffer before it is played
26652667 cdrom_regs[0x0b] = 0x00; // From Ootake v2.38.
2668+ //adpcm_dma_enabled = false;
26662669 //adpcm_do_dma();
26672670 } else {
26682671 adpcm_do_dma();
@@ -2693,33 +2696,17 @@ void PCE::write_signal(int id, uint32_t data, uint32_t mask)
26932696 set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_READY, CLEAR_LINE);
26942697 set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_DONE, CLEAR_LINE);
26952698 if(/*!(adpcm_play_in_progress) && */(adpcm_dma_enabled)){
2696- #ifdef USE_SEPARATED_ADPCM
2697- //d_adpcm->write_signal(SIG_ADPCM_DMACTRL, cdrom_regs[0x0b], 0xff);
2698- //d_adpcm->write_signal(SIG_ADPCM_PAUSE, 0xff, 0xff);
2699- //cdrom_regs[0x0b] = d_adpcm->read_signal(SIG_ADPCM_DMACTRL);
2700- #else
2701- adpcm_pause(true);
2702- #endif
27032699 //adpcm_dma_enabled = false;
2704- out_debug_log(_T("SIG_PCE_SCSI_BSY: PAUSE ADPCM\n"));
2700+ //out_debug_log(_T("SIG_PCE_SCSI_BSY: DISABLE DMA\n"));
27052701 }
27062702 } else {
27072703 if(/*!(adpcm_play_in_progress) && */(adpcm_dma_enabled)){
27082704 #ifdef USE_SEPARATED_ADPCM
2709- {
2710- d_adpcm->write_signal(SIG_ADPCM_DMACTRL, cdrom_regs[0x0b], 0xff);
2711- d_adpcm->write_signal(SIG_ADPCM_DO_DMA_TRANSFER, 0xff, 0xff);
2712- cdrom_regs[0x0b] = d_adpcm->read_signal(SIG_ADPCM_DMACTRL);
2713- //d_adpcm->write_signal(SIG_ADPCM_PAUSE, 0x00, 0xff);
2714- }
2705+ d_adpcm->write_signal(SIG_ADPCM_DO_DMA_TRANSFER, 0xff, 0xff);
27152706 #else
2716- if(adpcm_play_in_progress) {
2717- adpcm_do_dma();
2718- adpcm_pause(false);
2719- }
2707+ adpcm_do_dma();
27202708 #endif
2721- //adpcm_dma_enabled = false;
2722- out_debug_log(_T("SIG_PCE_SCSI_BSY: UNPAUSE ADPCM\n"));
2709+ out_debug_log(_T("SIG_PCE_SCSI_BSY: BUS CONNECT\n"));
27232710 }
27242711 }
27252712 break;
@@ -2744,91 +2731,54 @@ void PCE::write_signal(int id, uint32_t data, uint32_t mask)
27442731 uint8_t msm_data = (msm_nibble) ? (adpcm_ram[msm_start_addr & 0xffff] & 0x0f) : ((adpcm_ram[msm_start_addr & 0xffff] & 0xf0) >> 4);
27452732 d_msm->data_w(msm_data);
27462733 msm_nibble ^= 1;
2747-
2734+ bool need_wait = false;
27482735 if(msm_nibble == 0) {
27492736 if(adpcm_written >= 0) adpcm_written--;
27502737 // 20181213 K.O: Re-order sequence from Ootake v2.83.Thanks to developers of Ootake.
2751- //if((msm_start_addr & 0xffff) == msm_end_addr) {
2752- if(!(adpcm_dma_enabled) && ((msm_start_addr & 0xffff) == msm_end_addr)) {
2753- // stop playing adpcm
2754- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE);
2755- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
2756- //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE);
2757- adpcm_stop(false); // true?
2758- d_msm->reset_w(1);
2759- /*
2760- if(adpcm_repeat) {
2761- msm_start_addr = (adpcm_read_ptr) & 0xffff;
2762- msm_end_addr = (adpcm_read_ptr + adpcm_length) & 0xffff;
2763- msm_half_addr = (adpcm_read_ptr + (adpcm_length / 2)) & 0xffff;
2764- adpcm_write_ptr &= 0xffff;
2765- msm_nibble = 0;
2766- adpcm_play_in_progress = true;
2767- adpcm_play();
2768- d_msm->reset_w(0);
2769- }
2770- */
2771- out_debug_log(_T("END ADDRESS(NON-DMA) MSM_ADDR=%08x\n"), msm_start_addr);
2772- adpcm_stream = false;
2773- adpcm_repeat = false;
2774- } else if(((msm_start_addr & 0xffff) == msm_end_addr) && (adpcm_dma_enabled)) {
2775- // reached to end address
2776- if((adpcm_repeat) &&
2777- (adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff) /* && (IsHuVideo()) */) {
2778- adpcm_written++;
2779- msm_start_addr = msm_start_addr - 1;
2780- goto __skip1;
2781- }
2782- /*if(adpcm_written == 0) */{
2783- // restart streaming
2738+ if((msm_start_addr & 0xffff) == (msm_end_addr & 0xffff)) {
2739+ //if((adpcm_dma_enabled) && ((cdrom_regs[0x0d] & 0x10) != 0)) {
2740+ // set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE);
2741+ // set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE);
2742+ // break;
2743+ //}
2744+ /*if((adpcm_repeat) && ((adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff))) {
2745+ need_wait = true;
2746+ } else */{
27842747 set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE);
2748+ //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
27852749 set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE);
2786- //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE);
2787- out_debug_log(_T("END ADDRESS(DMA) MSM_ADDR=%08x\n"), msm_start_addr);
2788- //msm_start_addr = msm_start_addr & 0xffff; // Continue
2789-#if 1
2790- //if(!(adpcm_repeat)) {
2791- adpcm_stop(true); // true?
2792- d_msm->reset_w(1);
2793- //} else {
2794- //adpcm_pause(true);
2795- //d_msm->reset_w(0);
2796- //}
2797-#endif
2750+ //if(!(adpcm_stream) && !(adpcm_dma_enabled)) {
2751+ adpcm_stop(false); // true?
2752+ d_msm->reset_w(1);
2753+ //}
27982754 adpcm_stream = false;
27992755 adpcm_repeat = false;
2800- }
2801- } else if(adpcm_dma_enabled && adpcm_written == 0) {
2802- // finish streaming when all samples are played
2803- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE);
2804- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE);
2805- out_debug_log(_T("ADPCM DMA QUEUE EMPTY MSM_ADDR=%08x\n"), msm_start_addr);
2806- //adpcm_stop(true);
2807- //d_msm->reset_w(1);
2808- //adpcm_stream = false;
2809- //adpcm_repeat = false;
2810- //goto __skip1;
2811- } else if((msm_start_addr & 0xffff) == msm_half_addr) {
2812- // reached to half address
2813- // 20181213 K.O: Porting from Ootake v2.83.Thanks to developers of Ootake.
2814- if((adpcm_dma_enabled) && (adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff)) {
2815- msm_half_addr = (msm_half_addr + 0x85) & 0xffff;
2756+ }
2757+ }
2758+ __skip0:
2759+ if(!(need_wait)) {
2760+ msm_start_addr++;
2761+ adpcm_read_ptr = msm_start_addr;
2762+ if((adpcm_repeat) && (adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff)) {
2763+ if((msm_start_addr & 0xffff) == (msm_half_addr & 0xffff)) {
2764+ msm_half_addr = msm_half_addr + 0x85;
2765+ set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, ASSERT_LINE);
2766+ set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
2767+ }
28162768 } else if(adpcm_length < 0x7fff) {
2817- msm_half_addr = (msm_half_addr + (uint16_t)(adpcm_length - 1024)) & 0xffff;
2769+ if((msm_start_addr & 0xffff) == (msm_half_addr & 0xffff)) {
2770+ msm_half_addr = msm_half_addr + ((adpcm_length - 1024) & 0xffff);
2771+ set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, ASSERT_LINE);
2772+ set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
2773+ }
2774+ } else {
2775+ if(((msm_start_addr & 0xffff) == 0x8000) ||
2776+ ((msm_start_addr & 0xffff) == 0x8000)) {
2777+ set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, ASSERT_LINE);
2778+ set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
2779+ }
28182780 }
2819- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
2820- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, ASSERT_LINE);
2821- out_debug_log(_T("HALF ADDRESS MSM_ADDR=%08x\n"), msm_start_addr);
2822- } else if((!((adpcm_dma_enabled) && (adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff)) &&
2823- !(adpcm_length < 0x7fff)) &&
2824- (((msm_start_addr & 0xffff) == 0x8000) || ((msm_start_addr & 0xffff) == 0x0000))) {
2825- // 20181213 K.O: Porting from Ootake v2.83.Thanks to developers of Ootake.
2826- //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE);
2827- set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, ASSERT_LINE);
2828- out_debug_log(_T("SPECIAL HALF ADDRESS MSM_ADDR=%08x\n"), msm_start_addr);
2829- }
2830-
2831- msm_start_addr++;
2781+ }
28322782 __skip1:
28332783 if(adpcm_dma_enabled) {
28342784 if(((adpcm_write_ptr & 0xffff) < (msm_start_addr & 0xffff) )) {
@@ -2855,7 +2805,7 @@ void PCE::write_signal(int id, uint32_t data, uint32_t mask)
28552805 d_scsi_host->read_signal(SIG_SCSI_MSG) == 0 &&
28562806 d_scsi_host->read_signal(SIG_SCSI_IO ) != 0) {
28572807 // already data is received, read next byte
2858- adpcm_pause(false); // Unpause if paused && data in.
2808+ //adpcm_pause(false); // Unpause if paused && data in.
28592809 adpcm_do_dma();
28602810 }
28612811 //}
--- a/source/src/vm/pcengine/pcengine.h
+++ b/source/src/vm/pcengine/pcengine.h
@@ -39,7 +39,7 @@
3939 #define USE_JOY_BUTTON_CAPTIONS
4040 #define USE_DEBUGGER
4141 #define USE_STATE
42-#define USE_SEPARATED_ADPCM
42+//#define USE_SEPARATED_ADPCM
4343
4444 #include "../../common.h"
4545 #include "../../fileio.h"
Show on old repository browser