data = data & ~0x85;
data = data | 0x08;
} else {
- data = data | 0x01;
data = data & ~0x0c;
+ data = data | 0x01;
}
+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff);
return data;
}
break;
adpcm_stream = false;
adpcm_repeat = false;
dma_enabled = false;
+ dma_connected = false;
play_in_progress = false;
adpcm_paused = false;
void ADPCM::set_dma_status(bool flag)
{
dma_enabled = flag;
+ if(!(flag)) {
+ dma_connected = false;
+ }
d_pce->write_signal(SIG_PCE_ADPCM_DMA, (flag) ? 0xffffffff : 0x00000000, 0xffffffff);
}
case SIG_ADPCM_DMA_ENABLED:
set_dma_status(flag);
if((flag)/* && (flag != dma_enabled)*/) {
+ dma_connected = true;
reg_0c |= ADPCM_REMAIN_WRITE_BUF;
if(d_pce->read_signal(SIG_PCE_CDROM_DATA_IN) != 0) {
do_dma(d_pce->read_signal(SIG_PCE_CDROM_RAW_DATA));
do_cmd(data);
break;
case SIG_ADPCM_WRITE_DMA_DATA:
+ reg_0c |= ADPCM_REMAIN_WRITE_BUF;
do_dma(data);
break;
case SIG_ADPCM_DO_DMA_TRANSFER:
- if((play_in_progress) && ((write_ptr & 0xffff) >= (msm_ptr & 0xffff))) {
- // now streaming, wait dma not to overwrite buffer before it is played
- reg_0b = 0x00;// From Ootake v2.38.
+ //if((play_in_progress) && ((write_ptr & 0xffff) >= (msm_ptr & 0xffff))) {
+ // // now streaming, wait dma not to overwrite buffer before it is played
+ // reg_0b = 0x00;// From Ootake v2.38.
+ // dma_connected = false;
//set_dma_status(false); // DON'T MODIFY PCE's DMA STATUS (HACK by K.O 20190212)
- } else {
- set_dma_status(true);
+ //} else {
+ //set_dma_status(true);
+ dma_connected = true;
+ reg_0c |= ADPCM_REMAIN_WRITE_BUF;
do_dma(d_pce->read_signal(SIG_PCE_CDROM_RAW_DATA));
- }
+ //}
break;
case SIG_ADPCM_FORCE_DMA_TRANSFER:
if(flag) {
+ dma_connected = true;
+ reg_0c |= ADPCM_REMAIN_WRITE_BUF;
do_dma(d_pce->read_signal(SIG_PCE_CDROM_RAW_DATA));
}
break;
+ case SIG_ADPCM_DMA_RELEASED:
+ if(flag) {
+ dma_connected = false;
+ }
case SIG_ADPCM_ADDR_HI: // REG $09
if((msm_last_cmd & 0x80) == 0) {
addr_reg.b.h = data;
void ADPCM::update_length()
{
adpcm_length = (uint32_t)(addr_reg.w) & 0xffff;
- msm_length = adpcm_length;
+ msm_length = adpcm_length + 1;
out_debug_log(_T("ADPCM SET LENGTH TO %04x\n"), adpcm_length);
}
(_clk < 16000)) {
adpcm_length = adpcm_length & 0x7fff;
}
- msm_length = adpcm_length;
out_debug_log(_T("ADPCM SET LENGTH LENGTH=%04x\n"), adpcm_length);
}
if(((cmd & 0x02) != 0) && ((msm_last_cmd & 0x02) == 0)) {
// ADPCM play
half_addr = (read_ptr + ((adpcm_length + 1) >> 1)) & 0xffff;
write_ptr &= 0xffff;
- //written_size = 0; // OK?
+ if(!(play_in_progress)) written_size = 0; // OK?
msm_nibble = 0;
play_in_progress = true;
+ msm_length = adpcm_length + 1; // OK?
do_play();
d_msm->reset_w(0);
out_debug_log(_T("ADPCM START PLAY(%s) START=%04x LENGTH=%04x HALF=%04x STREAM=%s\n"), (dma_enabled) ? _T("DMA") : _T("PIO"), msm_ptr, msm_length, half_addr, (adpcm_stream) ? _T("YES") : _T("NO"));
// set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE);
adpcm_stream = false;
adpcm_repeat = false;
- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff);
- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
- do_stop(false);
+ //d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff);
+ //d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff);
+ do_stop(true); // false?
out_debug_log(_T("ADPCM STATUS UPDATE PLAY=%s\n"), (play_in_progress) ? _T("YES") : _T("NO"));
}
msm_last_cmd = cmd;
if((flag)) {
{
if((play_in_progress) && !(adpcm_paused)) {
- //if(!((adpcm_length == 1) && ((msm_nibble & 1) == 0))) {
msm_data = (msm_nibble != 0) ? (ram[msm_ptr & 0xffff] & 0x0f) : ((ram[msm_ptr & 0xffff] & 0xf0) >> 4);
//}
d_msm->data_w(msm_data);
msm_nibble ^= 1;
bool need_wait =false;
if((msm_nibble == 0)) {
- if((written_size > 0) /*&& !(adpcm_stopped)*/) written_size--;
// Increment pointers.
// 20181213 K.O: Re-order sequence from Ootake v2.83.Thanks to developers of Ootake.
- if((msm_length == 0) && ((msm_last_cmd & 0x10) == 0)) {
- if((adpcm_repeat) && ((adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff))) {
- need_wait = true;
- msm_length++;
- } else {
- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff);
- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
- if((msm_last_cmd & 0x40) != 0) {
- do_stop(true); // true?
- d_msm->reset_w(1);
+ if(((dma_enabled) && !(dma_connected)) || !(dma_enabled)) {
+ if((msm_length == 0) && ((msm_last_cmd & 0x10) == 0)) {
+ //if((adpcm_repeat) && ((adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff))) {
+ // need_wait = true;
+ msm_length++;
+ //} else
+ {
+ d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff);
+ d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
+ if((msm_last_cmd & 0x40) != 0) {
+ do_stop(false); // true?
+ d_msm->reset_w(1);
+ }
+ adpcm_stream = false;
+ adpcm_repeat = false;
}
- adpcm_stream = false;
- adpcm_repeat = false;
}
}
+ if((written_size > 0) /*&& !(adpcm_stopped)*/) written_size--;
__skip0:
if(!(need_wait)) {
+
msm_ptr++;
msm_ptr = msm_ptr & 0xffff;
read_ptr = msm_ptr;
if(msm_length > 0) msm_length--;
- if(msm_length >= 0x10000) msm_length = 0xffff;
+ if(msm_length < 0) msm_length = 0;
+ if(msm_length > 0x10000) msm_length = 0x10000;
if((adpcm_repeat) && (adpcm_length >= 0x8000) && (adpcm_length <= 0x80ff)) {
if(msm_ptr == (half_addr & 0xffff)) {
half_addr = half_addr + 0x85;
+ msm_length = (msm_length + 0x85 + 0x85); // OK?
d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff);
+ //d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff);
}
} else if(adpcm_length < 0x7fff) {
if(msm_ptr == (half_addr & 0xffff)) {
half_addr = half_addr + ((adpcm_length - 1024) & 0xffff);
+ msm_length = (msm_length + ((adpcm_length - 1024) & 0xffff) * 2);
+ if(msm_length > 0x10000) msm_length = 0x10000;
d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff);
+ //d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff);
}
} else if((msm_ptr == 0x8000) || (msm_ptr == 0x0000)) {
d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0xffffffff, 0xffffffff);
d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff);
- } /*else if((msm_length == 0) && ((msm_last_cmd & 0x10) == 0)){
- d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff);
- d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff);
- if((msm_last_cmd & 0x40) != 0) {
- do_stop(true); // true?
- d_msm->reset_w(1);
- adpcm_stream = false;
- adpcm_repeat = false;
- }
- }*/
-
+ }
}
#if 1
__skip1:
if(dma_enabled) {
- if((write_ptr & 0xffff) < (msm_ptr & 0xffff)) {
+ if(((write_ptr & 0xffff) < (msm_ptr & 0xffff)) ||
+ (written_size <= 0)) {
+ reg_0c |= ADPCM_REMAIN_WRITE_BUF;
if(d_pce->read_signal(SIG_PCE_CDROM_DATA_IN) != 0) {
//do_pause(false); // Unpause if paused && data in.
do_dma(d_pce->read_signal(SIG_PCE_CDROM_RAW_DATA));
}
} else {
if((dma_enabled) && (play_in_progress)) {
+ reg_0c |= ADPCM_REMAIN_WRITE_BUF;
if(d_pce->read_signal(SIG_PCE_CDROM_DATA_IN) != 0) {
//do_pause(false); // Unpause if paused && data in.
do_dma(d_pce->read_signal(SIG_PCE_CDROM_RAW_DATA));
{
ram[write_ptr & 0xffff] = data;
write_ptr = (write_ptr + 1) & 0xffff;
- written_size = (written_size + 1) & 0xffff;;
- //if(msm_length < 0x10000) msm_length++;
+ if(written_size < 0) written_size = 0;
+ if(written_size < 0xffff) written_size = written_size + 1;
+ if(msm_length < 0x10000) msm_length++;
set_ack(0);
reg_0c &= ~ADPCM_REMAIN_WRITE_BUF;
state_fio->StateValue(written_size);
state_fio->StateValue(dma_enabled);
+ state_fio->StateValue(dma_connected);
state_fio->StateValue(play_in_progress);
state_fio->StateValue(adpcm_paused);
state_fio->StateValue(adpcm_stream);
check_read6_status_flag = true;
clear_ack();
set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_DONE, ASSERT_LINE);
+ d_adpcm->write_signal(SIG_ADPCM_DMA_RELEASED, 0xff, 0xff);
}
}
break;
check_read6_status_flag = true;
clear_ack();
set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_DONE, ASSERT_LINE);
+ d_adpcm->write_signal(SIG_ADPCM_DMA_RELEASED, 0xff, 0xff);
}
}
void PCE::set_cdrom_irq_line(int num, int state)
{
- if(((num & PCE_CD_IRQ_SAMPLE_FULL_PLAY) != 0) || ((num & PCE_CD_IRQ_SAMPLE_HALF_PLAY) != 0)) { // 20190212 K.O from mednafen.
- cdrom_regs[0x03] &= ~(PCE_CD_IRQ_SAMPLE_FULL_PLAY | PCE_CD_IRQ_SAMPLE_HALF_PLAY);
- }
+// if(((num & PCE_CD_IRQ_SAMPLE_FULL_PLAY) != 0) || ((num & PCE_CD_IRQ_SAMPLE_HALF_PLAY) != 0)) { // 20190212 K.O from mednafen.
+// cdrom_regs[0x03] &= ~(PCE_CD_IRQ_SAMPLE_FULL_PLAY | PCE_CD_IRQ_SAMPLE_HALF_PLAY);
+// }
if (state == ASSERT_LINE) {
cdrom_regs[0x03] |= num;
} else {
#ifdef USE_SEPARATED_ADPCM
switch(id) {
case SIG_PCE_CDROM_RAW_DATA:
- data = read_cdrom_data();
- set_ack();
+ { // MAYBE same as READ_1808().
+ bool read6_data_in = false;
+ if(d_scsi_cdrom->get_cur_command() == SCSI_CMD_READ6 &&
+ d_scsi_host->read_signal(SIG_SCSI_BSY) != 0 &&
+ d_scsi_host->read_signal(SIG_SCSI_REQ) != 0 &&
+ d_scsi_host->read_signal(SIG_SCSI_CD ) == 0 &&
+ d_scsi_host->read_signal(SIG_SCSI_MSG) == 0 &&
+ d_scsi_host->read_signal(SIG_SCSI_IO ) != 0) {
+ // read6 command, data in phase
+ read6_data_in = true;
+ }
+ data = read_cdrom_data();
+ if(read6_data_in) {
+ // set ack automatically and immediately for correct transfer speed
+ set_ack();
+ // XXX: Hack to wait until next REQ signal is raised
+ // because PCE does not check REQ signal before reads next byte
+ //d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
+ check_read6_status_flag = false;
+ } else if(!(check_read6_status_flag) &&
+ (d_scsi_cdrom->get_cur_command() == SCSI_CMD_READ6) &&
+ (d_scsi_host->read_signal(SIG_SCSI_BSY) == 0) &&
+ (d_scsi_host->read_signal(SIG_SCSI_REQ) == 0) &&
+ (d_scsi_host->read_signal(SIG_SCSI_CD ) == 0) &&
+ (d_scsi_host->read_signal(SIG_SCSI_MSG) == 0) &&
+ (d_scsi_host->read_signal(SIG_SCSI_IO ) == 0)) { // BUS FREE
+ check_read6_status_flag = true;
+ clear_ack();
+ set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_DONE, ASSERT_LINE);
+ d_adpcm->write_signal(SIG_ADPCM_DMA_RELEASED, 0xff, 0xff);
+ }
+ }
//cdrom_regs[0x0c] &= ~0x04;
break;
case SIG_PCE_CDROM_DATA_IN:
set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_READY, CLEAR_LINE);
set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_DONE, CLEAR_LINE);
if(/*!(adpcm_play_in_progress) && */(adpcm_dma_enabled)){
+ d_adpcm->write_signal(SIG_ADPCM_DMA_RELEASED, 0xff, 0xff);
//adpcm_dma_enabled = false;
- //out_debug_log(_T("SIG_PCE_SCSI_BSY: DISABLE DMA\n"));
+ out_debug_log(_T("SIG_PCE_SCSI_BSY: FREE DMA BUS\n"));
}
} else {
if(/*!(adpcm_play_in_progress) && */(adpcm_dma_enabled)){
#else
adpcm_do_dma();
#endif
- out_debug_log(_T("SIG_PCE_SCSI_BSY: BUS CONNECT\n"));
+ out_debug_log(_T("SIG_PCE_SCSI_BSY: CONNECT DMA BUS\n"));
}
}
break;