Common Source Code Project for Qt (a.k.a for FM-7).
Revision | e1999e69c01c38ed62520492980178331523f3f6 (tree) |
---|---|
Time | 2018-12-11 05:12:35 |
Author | K.Ohta <whatisthis.sowhat@gmai...> |
Commiter | K.Ohta |
[VM][PCENGINE][ADPCM][WIP] Porting from Ootake v2.83.This still WORK-IN-PROGRESS.
@@ -1887,8 +1887,11 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) | ||
1887 | 1887 | d_scsi_host->write_signal(SIG_SCSI_SEL, 0, 1); |
1888 | 1888 | adpcm_dma_enabled = false; |
1889 | 1889 | // From Ootake v2.38 |
1890 | + //d_scsi_host->write_signal(SIG_SCSI_RST, 0xff, 0xff); | |
1891 | + //d_scsi_cdrom->reset_device(); | |
1890 | 1892 | cdrom_regs[0x03] = 0x00; // Reset IRQ status at al. |
1891 | - set_cdrom_irq_line(0x70, CLEAR_LINE); | |
1893 | + //set_cdrom_irq_line(0x70, CLEAR_LINE); | |
1894 | + set_cdrom_irq_line(0x0, 0x0); // Update IRQ | |
1892 | 1895 | break; |
1893 | 1896 | |
1894 | 1897 | case 0x01: /* CDC command / status / data */ |
@@ -1921,6 +1924,8 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) | ||
1921 | 1924 | // Reset ADPCM hardware |
1922 | 1925 | reset_adpcm(); |
1923 | 1926 | set_cdrom_irq_line(0x70, CLEAR_LINE); |
1927 | + adpcm_dma_enabled = false; | |
1928 | + out_debug_log(_T("ADPCM CMD=$04 RESET\n")); | |
1924 | 1929 | |
1925 | 1930 | } |
1926 | 1931 | d_scsi_host->write_signal(SIG_SCSI_RST, data, 0x02); |
@@ -1952,6 +1957,7 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) | ||
1952 | 1957 | if(data & 3) { |
1953 | 1958 | /* Start CD to ADPCM transfer */ |
1954 | 1959 | adpcm_dma_enabled = true; |
1960 | + cdrom_regs[0x0c] |= 0x04; | |
1955 | 1961 | if(d_scsi_cdrom->get_cur_command() == SCSI_CMD_READ6 && |
1956 | 1962 | d_scsi_host->read_signal(SIG_SCSI_BSY) != 0 && |
1957 | 1963 | d_scsi_host->read_signal(SIG_SCSI_REQ) != 0 && |
@@ -1962,9 +1968,11 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) | ||
1962 | 1968 | adpcm_do_dma(); |
1963 | 1969 | out_debug_log(_T("Start DMA port $0B/ALREADY READ DATA ADPCM_WRITE_PTR=%04x ADPCM_READ_PTR=%04x MSM_START_ADDR=%04x\n"),adpcm_write_ptr, adpcm_read_ptr, msm_start_addr); |
1964 | 1970 | } else { |
1965 | - cdrom_regs[0x0c] |= 0x04; | |
1971 | + //cdrom_regs[0x0c] |= 0x04; | |
1966 | 1972 | out_debug_log(_T("Start DMA port $0B/WAIT FOR DATA\n")); |
1967 | 1973 | } |
1974 | + } else { | |
1975 | + //adpcm_dma_enabled = false; | |
1968 | 1976 | } |
1969 | 1977 | break; |
1970 | 1978 |
@@ -1975,6 +1983,8 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) | ||
1975 | 1983 | if((cdrom_regs[0x0d] & 0x80) && !(data & 0x80)) { |
1976 | 1984 | // Reset ADPCM hardware |
1977 | 1985 | reset_adpcm(); |
1986 | + adpcm_stop(true); | |
1987 | + out_debug_log(_T("ADPCM CMD=$0D RESET\n")); | |
1978 | 1988 | } |
1979 | 1989 | if(data & 0x02) { |
1980 | 1990 | // ADPCM set write address |
@@ -1992,9 +2002,19 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) | ||
1992 | 2002 | if(data & 0x10) { |
1993 | 2003 | // ADPCM set length |
1994 | 2004 | adpcm_length = (cdrom_regs[0x09] << 8) | cdrom_regs[0x08]; |
2005 | + uint32_t _clk = (ADPCM_CLOCK / 6) / adpcm_clock_divider; | |
2006 | + | |
2007 | + if(((adpcm_read_ptr & 0xffff) >= 0x4000) && | |
2008 | + ((adpcm_write_ptr & 0xffff) == 0x0000) && | |
2009 | + (adpcm_length != 0x8000) && | |
2010 | + (adpcm_length != 0xffff) && | |
2011 | + (_clk < 16000)) { | |
2012 | + adpcm_length = adpcm_length & 0x7fff; | |
2013 | + } | |
1995 | 2014 | out_debug_log(_T("ADPCM SET LENGTH LENGTH=%04x\n"), adpcm_length); |
1996 | 2015 | } |
1997 | - if((data & 0x40) && ((cdrom_regs[0x0D] & 0x40) == 0)) { | |
2016 | + if((((data & 0x40) != 0) && ((cdrom_regs[0x0D] & 0x40) == 0)) || | |
2017 | + (!(adpcm_play_in_progress) && ((data & 0x20 != 0)))) { // From Ootake v2.83 | |
1998 | 2018 | // ADPCM play |
1999 | 2019 | msm_start_addr = (adpcm_read_ptr) & 0xffff; |
2000 | 2020 | msm_end_addr = (adpcm_read_ptr + adpcm_length) & 0xffff; |
@@ -2005,7 +2025,13 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) | ||
2005 | 2025 | adpcm_play(); |
2006 | 2026 | d_msm->reset_w(0); |
2007 | 2027 | out_debug_log(_T("ADPCM START PLAY START=%04x END=%04x HALF=%04x\n"), msm_start_addr, msm_end_addr, msm_half_addr); |
2008 | - } else if ((data & 0x40) == 0) { | |
2028 | + } /*else if(((data & 0x40) == 0) && ((cdrom_regs[0x0D] & 0x40) != 0) && (adpcm_play_in_progress)) { | |
2029 | + if(((data & 0x20) != 0) && ((adpcm_length & 0xffff) >= 0x8000) && ((adpcm_length & 0xffff) <= 0x80ff)) { | |
2030 | + msm_half_addr = (adpcm_read_ptr + 0x85) & 0xffff; | |
2031 | + } else { | |
2032 | + msm_half_addr = (adpcm_read_ptr + (adpcm_length >> 1)) & 0xffff; | |
2033 | + } | |
2034 | + } */else if ((data & 0x40) == 0) { | |
2009 | 2035 | // used by Buster Bros to cancel an in-flight sample |
2010 | 2036 | // if repeat flag (bit5) is high, ADPCM should be fully played (from Ootake) |
2011 | 2037 | if(!(data & 0x20)) { |
@@ -2068,11 +2094,24 @@ uint8_t PCE::cdrom_read(uint16_t addr) | ||
2068 | 2094 | case 0xc6: return 0x55; |
2069 | 2095 | case 0xc7: return 0x03; |
2070 | 2096 | } |
2097 | + return 0xff; // From Ootake v2.83. | |
2071 | 2098 | } |
2072 | 2099 | uint8_t data = cdrom_regs[addr & 0x0f]; |
2073 | 2100 | |
2074 | 2101 | switch(addr & 0x0f) { |
2075 | 2102 | case 0x00: /* CDC status */ |
2103 | + if((cdrom_regs[0x02] & 0x80) != 0) { | |
2104 | + // ToDo: Imprement read_1801() at Ootake v2.83. | |
2105 | + // ToDo: Implement _CheckCountAfterRead at CDROM.cpp of Ootake v2.83. | |
2106 | + if((d_scsi_host->read_signal(SIG_SCSI_CD) != 0) && | |
2107 | + (d_scsi_host->read_signal(SIG_SCSI_MSG) == 0) && | |
2108 | + (d_scsi_host->read_signal(SIG_SCSI_IO) != 0)) { // STATUS PHASE: Porting from Ootake v2.83. | |
2109 | + // // busy = false; | |
2110 | + cdrom_regs[0x02] = cdrom_regs[0x02] & ~(0x80 | PCE_CD_IRQ_TRANSFER_READY | PCE_CD_IRQ_TRANSFER_DONE); | |
2111 | + set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_DONE, CLEAR_LINE); | |
2112 | + } | |
2113 | + return data & ~0x40; // Clear REQ | |
2114 | + } | |
2076 | 2115 | data = 0; |
2077 | 2116 | if(d_cpu->get_pc() == 0xf34b) { |
2078 | 2117 | // XXX: Hack to wait the CD-DA will be finished for the Manhole |
@@ -2083,7 +2122,28 @@ uint8_t PCE::cdrom_read(uint16_t addr) | ||
2083 | 2122 | data |= d_scsi_host->read_signal(SIG_SCSI_MSG) ? 0x20 : 0; |
2084 | 2123 | data |= d_scsi_host->read_signal(SIG_SCSI_CD ) ? 0x10 : 0; |
2085 | 2124 | data |= d_scsi_host->read_signal(SIG_SCSI_IO ) ? 0x08 : 0; |
2086 | - | |
2125 | + cdrom_regs[0x00] = data; | |
2126 | + if(false){ | |
2127 | + // Import from Ootake v2.83 20181211 K.O | |
2128 | + if(((data & 0x10) != 0) && | |
2129 | + ((data & 0x20) == 0) && | |
2130 | + ((data & 0x08) == 0)){ // Command phase | |
2131 | + if((data & 0x80) != 0) { // Busy | |
2132 | + // data = (data & ~0x40) | 0x08; // (data & ~REQ) | IO | |
2133 | + } else { | |
2134 | + //data = data & ~0x40; // (data & ~REQ) | |
2135 | + } | |
2136 | + } else if((data & 0x80) != 0) { // BUSY | |
2137 | + data = (data & ~0x40) | 0x10 | 0x80; // (data & ~REQ) | BUSY | CD | |
2138 | + } /*else if(_CheckCountAfterRead == 0) && (Status phase) && (cmd == read6)){ | |
2139 | + data = data & ~0x40; | |
2140 | + } else */ /* if(_bCDReqWait) { | |
2141 | + _bCDReqWait = false; | |
2142 | + if(data boundary) { | |
2143 | + data = data & ~0x40; | |
2144 | + } | |
2145 | + }*/ | |
2146 | + } | |
2087 | 2147 | break; |
2088 | 2148 | |
2089 | 2149 | case 0x01: /* CDC command / status / data */ |
@@ -2100,7 +2160,6 @@ uint8_t PCE::cdrom_read(uint16_t addr) | ||
2100 | 2160 | read6_data_in = true; |
2101 | 2161 | } |
2102 | 2162 | data = read_cdrom_data(); |
2103 | - | |
2104 | 2163 | if(read6_data_in) { |
2105 | 2164 | // set ack automatically and immediately for correct transfer speed |
2106 | 2165 | set_ack(); |
@@ -2108,6 +2167,11 @@ uint8_t PCE::cdrom_read(uint16_t addr) | ||
2108 | 2167 | // XXX: Hack to wait until next REQ signal is raised |
2109 | 2168 | // because PCE does not check REQ signal before reads next byte |
2110 | 2169 | d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1); |
2170 | + } else { | |
2171 | + if((addr & 0x0f) == 0x01) { | |
2172 | + // ToDo: Imprement read_1801() at Ootake v2.83. | |
2173 | + // ToDo: Implement _CheckCountAfterRead at CDROM.cpp of Ootake v2.83. | |
2174 | + } | |
2111 | 2175 | } |
2112 | 2176 | } |
2113 | 2177 | break; |
@@ -2154,8 +2218,17 @@ uint8_t PCE::cdrom_read(uint16_t addr) | ||
2154 | 2218 | break; |
2155 | 2219 | |
2156 | 2220 | case 0x0c: /* ADPCM status */ |
2221 | + // Hack from Ootake v2.83. | |
2222 | + if(adpcm_play_in_progress) { | |
2223 | + data = data & ~0x85; | |
2224 | + data = data | 0x08; | |
2225 | + } else { | |
2226 | + data = data | 0x01; | |
2227 | + data = data & ~0x0c; | |
2228 | + } | |
2229 | + cdrom_regs[0x0c] = data; | |
2230 | + // ToDo: HuVideo | |
2157 | 2231 | break; |
2158 | - | |
2159 | 2232 | case 0x09: /* ADPCM address (MSB) */ |
2160 | 2233 | case 0x0d: /* ADPCM address control */ |
2161 | 2234 | case 0x0e: /* ADPCM playback rate */ |
@@ -2173,6 +2246,7 @@ void PCE::write_cdrom_data(uint8_t data) | ||
2173 | 2246 | |
2174 | 2247 | uint8_t PCE::read_cdrom_data() |
2175 | 2248 | { |
2249 | + | |
2176 | 2250 | return d_scsi_host->read_dma_io8(0); |
2177 | 2251 | } |
2178 | 2252 |
@@ -2234,6 +2308,7 @@ void PCE::adpcm_stop(bool do_irq) | ||
2234 | 2308 | cdrom_regs[0x0d] &= ~0x60; |
2235 | 2309 | msm_idle = 1; |
2236 | 2310 | adpcm_play_in_progress = false; |
2311 | +// adpcm_dma_enabled = false; | |
2237 | 2312 | out_debug_log(_T("ADPCM STOP PLAY PTR=%04x IRQ=%s\n"), msm_start_addr, (do_irq) ? _T("YES") : _T("NO")); |
2238 | 2313 | } |
2239 | 2314 |
@@ -2338,8 +2413,10 @@ void PCE::write_signal(int id, uint32_t data, uint32_t mask) | ||
2338 | 2413 | d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1); |
2339 | 2414 | |
2340 | 2415 | if(adpcm_dma_enabled) { |
2341 | - if(!(msm_idle) && (adpcm_write_ptr >= msm_start_addr)) { | |
2416 | + if(!(msm_idle) && ((adpcm_write_ptr & 0xffff) >= (msm_start_addr & 0xffff))) { | |
2342 | 2417 | // now streaming, wait dma not to overwrite buffer before it is played |
2418 | + cdrom_regs[0x0b] = 0x00; // From Ootake v2.38. | |
2419 | + //adpcm_do_dma(); | |
2343 | 2420 | } else { |
2344 | 2421 | adpcm_do_dma(); |
2345 | 2422 | } |
@@ -2411,6 +2488,7 @@ void PCE::write_signal(int id, uint32_t data, uint32_t mask) | ||
2411 | 2488 | // restart streaming |
2412 | 2489 | set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE); |
2413 | 2490 | set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, CLEAR_LINE); |
2491 | + //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE); | |
2414 | 2492 | out_debug_log(_T("END ADDRESS(DMA) READ_PTR=%04x WRITE_PTR=%04x\n"), adpcm_read_ptr, adpcm_write_ptr); |
2415 | 2493 | } else { |
2416 | 2494 | // stop playing adpcm |
@@ -17,8 +17,8 @@ | ||
17 | 17 | #define CDDA_PLAYING 1 |
18 | 18 | #define CDDA_PAUSED 2 |
19 | 19 | |
20 | -//#define _SCSI_DEBUG_LOG | |
21 | -//#define _CDROM_DEBUG_LOG | |
20 | +#define _SCSI_DEBUG_LOG | |
21 | +#define _CDROM_DEBUG_LOG | |
22 | 22 | |
23 | 23 | // 0-99 is reserved for SCSI_DEV class |
24 | 24 | #define EVENT_CDDA 100 |