| version 1.6, 2004/01/23 15:05:05 | version 1.8, 2005/02/07 14:46:12 | 
| Line 9 | Line 9 | 
 | extern  CS4231CFG       cs4231cfg; | extern  CS4231CFG       cs4231cfg; | 
 |  |  | 
 |  |  | 
| // ---- 補完くらいしようよ… | static void SOUNDCALL pcm8m(CS4231 cs, SINT32 *pcm, UINT count) { | 
 |  |  | 
| REG8 cs4231_nodecode(DMACH dmach) { | UINT    leng; | 
|  | UINT32  pos12; | 
| (void)dmach; | SINT32  fract; | 
| return(0); | UINT    samppos; | 
| } | const UINT8     *ptr1; | 
|  | const UINT8     *ptr2; | 
| static REG8 cs4231_pcm8s(DMACH dmach) { | SINT32  samp1; | 
|  | SINT32  samp2; | 
| SINT32  leng; |  | 
| UINT    indatas; | leng = cs->bufdatas >> 0; | 
| UINT32  addr; | if (!leng) { | 
| UINT32  ctime; | return; | 
| UINT    wpos; |  | 
|  |  | 
| leng = dmach->leng.w; |  | 
| if ((leng >= 2) && (cs4231.bufsize < CS4231_BUFFERS)) { |  | 
| indatas = cs4231.bufsize; |  | 
| ctime = cs4231.curtime; |  | 
| wpos = cs4231.writepos; |  | 
| addr = dmach->adrs.d; |  | 
| do { |  | 
| while(ctime < cs4231.step) { |  | 
| ctime += cs4231cfg.rate; |  | 
| leng -= 2; |  | 
| if (leng < 0) { |  | 
| leng = 0; |  | 
| goto p8s_stop; |  | 
| } |  | 
| cs4231.pcmdata[0] = (i286_memoryread(addr + 0) ^ 0x80) << 8; |  | 
| cs4231.pcmdata[1] = (i286_memoryread(addr + 1) ^ 0x80) << 8; |  | 
| addr += 2; |  | 
| } |  | 
| ctime -= cs4231.step; |  | 
| *(UINT32 *)(cs4231.buffer + wpos) = *(UINT32 *)cs4231.pcmdata, |  | 
| wpos = (wpos + 4) & (CS4231_BUFBYTES - 1); |  | 
| indatas++; |  | 
| } while(indatas < CS4231_BUFFERS); |  | 
|  |  | 
| p8s_stop: |  | 
| dmach->leng.w = leng; |  | 
| dmach->adrs.d = addr; |  | 
| cs4231.bufsize = indatas; |  | 
| cs4231.curtime = ctime; |  | 
| cs4231.writepos = wpos; |  | 
 | } | } | 
| return((leng < 2)?1:0); | pos12 = cs->pos12; | 
| } | do { | 
|  | samppos = pos12 >> 12; | 
| static REG8 cs4231_pcm8m(DMACH dmach) { | if (leng <= samppos) { | 
|  | break; | 
| SINT32  leng; | } | 
| UINT    indatas; | fract = pos12 & ((1 << 12) - 1); | 
| UINT32  addr; | ptr1 = cs->buffer + | 
| UINT32  ctime; | ((cs->bufpos + (samppos << 0) + 0) & CS4231_BUFMASK); | 
| UINT    wpos; | ptr2 = cs->buffer + | 
| SINT16  pcmdata; | ((cs->bufpos + (samppos << 0) + 1) & CS4231_BUFMASK); | 
|  | samp1 = (ptr1[0] - 0x80) << 8; | 
| leng = dmach->leng.w; | samp2 = (ptr2[0] - 0x80) << 8; | 
| if ((leng > 0) && (cs4231.bufsize < CS4231_BUFFERS)) { | samp1 += ((samp2 - samp1) * fract) >> 12; | 
| indatas = cs4231.bufsize; | pcm[0] += samp1; | 
| ctime = cs4231.curtime; | pcm[1] += samp1; | 
| wpos = cs4231.writepos; | pcm += 2; | 
| addr = dmach->adrs.d; | pos12 += cs->step12; | 
| do { | } while(--count); | 
| while(ctime < cs4231.step) { |  | 
| ctime += cs4231cfg.rate; | leng = min(leng, (pos12 >> 12)); | 
| leng -= 1; | cs->bufdatas -= (leng << 0); | 
| if (leng < 0) { | cs->bufpos += (leng << 0); | 
| leng = 0; | cs->pos12 = pos12 & ((1 << 12) - 1); | 
| goto p8m_stop; | } | 
| } |  | 
| pcmdata = (i286_memoryread(addr) ^ 0x80) << 8; | static void SOUNDCALL pcm8s(CS4231 cs, SINT32 *pcm, UINT count) { | 
| cs4231.pcmdata[0] = pcmdata; |  | 
| cs4231.pcmdata[1] = pcmdata; | UINT    leng; | 
| addr += 1; | UINT32  pos12; | 
| } | SINT32  fract; | 
| ctime -= cs4231.step; | UINT    samppos; | 
| *(UINT32 *)(cs4231.buffer + wpos) = *(UINT32 *)cs4231.pcmdata, | const UINT8     *ptr1; | 
| wpos = (wpos + 4) & (CS4231_BUFBYTES - 1); | const UINT8     *ptr2; | 
| indatas++; | SINT32  samp1; | 
| } while(indatas < CS4231_BUFFERS); | SINT32  samp2; | 
|  |  | 
| p8m_stop: | leng = cs->bufdatas >> 1; | 
| dmach->leng.w = leng; | if (!leng) { | 
| dmach->adrs.d = addr; | return; | 
| cs4231.bufsize = indatas; |  | 
| cs4231.curtime = ctime; |  | 
| cs4231.writepos = wpos; |  | 
 | } | } | 
| return((leng == 0)?1:0); | pos12 = cs->pos12; | 
| } | do { | 
|  | samppos = pos12 >> 12; | 
| static REG8 cs4231_pcm16s(DMACH dmach) { | if (leng <= samppos) { | 
|  | break; | 
| SINT32  leng; | } | 
| UINT    indatas; | fract = pos12 & ((1 << 12) - 1); | 
| UINT32  addr; | ptr1 = cs->buffer + | 
| UINT32  ctime; | ((cs->bufpos + (samppos << 1) + 0) & CS4231_BUFMASK); | 
| UINT    wpos; | ptr2 = cs->buffer + | 
| UINT16  samp; | ((cs->bufpos + (samppos << 1) + 2) & CS4231_BUFMASK); | 
|  | samp1 = (ptr1[0] - 0x80) << 8; | 
| leng = dmach->leng.w; | samp2 = (ptr2[0] - 0x80) << 8; | 
| if ((leng >= 4) && (cs4231.bufsize < CS4231_BUFFERS)) { | samp1 += ((samp2 - samp1) * fract) >> 12; | 
| indatas = cs4231.bufsize; | pcm[0] += samp1; | 
| ctime = cs4231.curtime; | samp1 = (ptr1[1] - 0x80) << 8; | 
| wpos = cs4231.writepos; | samp2 = (ptr2[1] - 0x80) << 8; | 
| addr = dmach->adrs.d; | samp1 += ((samp2 - samp1) * fract) >> 12; | 
| // TRACEOUT(("addr: %x", addr)); | pcm[1] += samp1; | 
| do { | pcm += 2; | 
| while(ctime < cs4231.step) { | pos12 += cs->step12; | 
| ctime += cs4231cfg.rate; | } while(--count); | 
| leng -= 4; |  | 
| if (leng < 0) { | leng = min(leng, (pos12 >> 12)); | 
| leng = 0; | cs->bufdatas -= (leng << 1); | 
| goto p16s_stop; | cs->bufpos += (leng << 1); | 
| } | cs->pos12 = pos12 & ((1 << 12) - 1); | 
| samp = i286_memoryread_w(addr+0); | } | 
| cs4231.pcmdata[0] = (SINT16)((samp << 8) + (samp >> 8)); |  | 
| samp = i286_memoryread_w(addr+2); | static void SOUNDCALL pcm16m(CS4231 cs, SINT32 *pcm, UINT count) { | 
| cs4231.pcmdata[1] = (SINT16)((samp << 8) + (samp >> 8)); |  | 
| addr += 4; | UINT    leng; | 
| } | UINT32  pos12; | 
| ctime -= cs4231.step; | SINT32  fract; | 
| *(UINT32 *)(cs4231.buffer + wpos) = *(UINT32 *)cs4231.pcmdata, | UINT    samppos; | 
| wpos = (wpos + 4) & (CS4231_BUFBYTES - 1); | const UINT8     *ptr1; | 
| indatas++; | const UINT8     *ptr2; | 
| } while(indatas < CS4231_BUFFERS); | SINT32  samp1; | 
|  | SINT32  samp2; | 
| p16s_stop: |  | 
| dmach->leng.w = leng; | leng = cs->bufdatas >> 1; | 
| dmach->adrs.d = addr; | if (!leng) { | 
| cs4231.bufsize = indatas; | return; | 
| cs4231.curtime = ctime; |  | 
| cs4231.writepos = wpos; |  | 
 | } | } | 
| return((leng < 4)?1:0); | pos12 = cs->pos12; | 
| } | do { | 
|  | samppos = pos12 >> 12; | 
| static REG8 cs4231_pcm16m(DMACH dmach) { | if (leng <= samppos) { | 
|  | break; | 
| SINT32  leng; | } | 
| UINT    indatas; | fract = pos12 & ((1 << 12) - 1); | 
| UINT32  addr; | ptr1 = cs->buffer + | 
| UINT32  ctime; | ((cs->bufpos + (samppos << 1) + 0) & CS4231_BUFMASK); | 
| UINT    wpos; | ptr2 = cs->buffer + | 
| UINT16  samp; | ((cs->bufpos + (samppos << 1) + 2) & CS4231_BUFMASK); | 
|  | samp1 = (((SINT8)ptr1[0]) << 8) + ptr1[1]; | 
| leng = dmach->leng.w; | samp2 = (((SINT8)ptr2[0]) << 8) + ptr2[1]; | 
| if ((leng >= 2) && (cs4231.bufsize < CS4231_BUFFERS)) { | samp1 += ((samp2 - samp1) * fract) >> 12; | 
| indatas = cs4231.bufsize; | pcm[0] += samp1; | 
| ctime = cs4231.curtime; | pcm[1] += samp1; | 
| wpos = cs4231.writepos; | pcm += 2; | 
| addr = dmach->adrs.d; | pos12 += cs->step12; | 
| do { | } while(--count); | 
| while(ctime < cs4231.step) { |  | 
| ctime += cs4231cfg.rate; | leng = min(leng, (pos12 >> 12)); | 
| leng -= 2; | cs->bufdatas -= (leng << 1); | 
| if (leng < 0) { | cs->bufpos += (leng << 1); | 
| leng = 0; | cs->pos12 = pos12 & ((1 << 12) - 1); | 
| goto p16m_stop; | } | 
| } |  | 
| samp = i286_memoryread_w(addr); | static void SOUNDCALL pcm16s(CS4231 cs, SINT32 *pcm, UINT count) { | 
| samp = (UINT16)((samp << 8) + (samp >> 8)); |  | 
| cs4231.pcmdata[0] = (SINT16)samp; | UINT    leng; | 
| cs4231.pcmdata[1] = (SINT16)samp; | UINT32  pos12; | 
| addr += 2; | SINT32  fract; | 
| } | UINT    samppos; | 
| ctime -= cs4231.step; | const UINT8     *ptr1; | 
| *(UINT32 *)(cs4231.buffer + wpos) = *(UINT32 *)cs4231.pcmdata, | const UINT8     *ptr2; | 
| wpos = (wpos + 4) & (CS4231_BUFBYTES - 1); | SINT32  samp1; | 
| indatas++; | SINT32  samp2; | 
| } while(indatas < CS4231_BUFFERS); |  | 
|  | leng = cs->bufdatas >> 2; | 
| p16m_stop: | if (!leng) { | 
| dmach->leng.w = leng; | return; | 
| dmach->adrs.d = addr; |  | 
| cs4231.bufsize = indatas; |  | 
| cs4231.curtime = ctime; |  | 
| cs4231.writepos = wpos; |  | 
 | } | } | 
| return((leng < 2)?1:0); | pos12 = cs->pos12; | 
|  | do { | 
|  | samppos = pos12 >> 12; | 
|  | if (leng <= samppos) { | 
|  | break; | 
|  | } | 
|  | fract = pos12 & ((1 << 12) - 1); | 
|  | ptr1 = cs->buffer + | 
|  | ((cs->bufpos + (samppos << 2) + 0) & CS4231_BUFMASK); | 
|  | ptr2 = cs->buffer + | 
|  | ((cs->bufpos + (samppos << 2) + 4) & CS4231_BUFMASK); | 
|  | samp1 = (((SINT8)ptr1[0]) << 8) + ptr1[1]; | 
|  | samp2 = (((SINT8)ptr2[0]) << 8) + ptr2[1]; | 
|  | samp1 += ((samp2 - samp1) * fract) >> 12; | 
|  | pcm[0] += samp1; | 
|  | samp1 = (((SINT8)ptr1[2]) << 8) + ptr1[3]; | 
|  | samp2 = (((SINT8)ptr2[2]) << 8) + ptr2[3]; | 
|  | samp1 += ((samp2 - samp1) * fract) >> 12; | 
|  | pcm[1] += samp1; | 
|  | pcm += 2; | 
|  | pos12 += cs->step12; | 
|  | } while(--count); | 
|  |  | 
|  | leng = min(leng, (pos12 >> 12)); | 
|  | cs->bufdatas -= (leng << 2); | 
|  | cs->bufpos += (leng << 2); | 
|  | cs->pos12 = pos12 & ((1 << 12) - 1); | 
|  | } | 
|  |  | 
|  | static void SOUNDCALL nomake(CS4231 cs, SINT32 *pcm, UINT count) { | 
|  |  | 
|  | (void)cs; | 
|  | (void)pcm; | 
|  | (void)count; | 
 | } | } | 
 |  |  | 
| const CS4231DMA cs4231dec[16] = { |  | 
| cs4231_pcm8m,           // 0: 8bit PCM | typedef void (SOUNDCALL * CS4231FN)(CS4231 cs, SINT32 *pcm, UINT count); | 
| cs4231_pcm8s, |  | 
| cs4231_nodecode,        // 1: u-Law | static const CS4231FN cs4231fn[16] = { | 
| cs4231_nodecode, | pcm8m,          // 0: 8bit PCM | 
| cs4231_nodecode,        // 2: | pcm8s, | 
| cs4231_nodecode, | nomake,         // 1: u-Law | 
| cs4231_nodecode,        // 3: A-law | nomake, | 
| cs4231_nodecode, | nomake,         // 2: | 
| cs4231_nodecode,        // 4: | nomake, | 
| cs4231_nodecode, | nomake,         // 3: A-Law | 
| cs4231_nodecode,        // 5: ADPCM | nomake, | 
| cs4231_nodecode, | nomake,         // 4: | 
| cs4231_pcm16m,          // 6: 16bit PCM | nomake, | 
| cs4231_pcm16s, | nomake,         // 5: ADPCM | 
| cs4231_nodecode,        // 7: ADPCM | nomake, | 
| cs4231_nodecode}; | pcm16m,         // 6: 16bit PCM | 
|  | pcm16s, | 
|  | nomake,         // 7: ADPCM | 
|  | nomake}; | 
 |  |  | 
 |  |  | 
 | // ---- | // ---- | 
 |  |  | 
 | void SOUNDCALL cs4231_getpcm(CS4231 cs, SINT32 *pcm, UINT count) { | void SOUNDCALL cs4231_getpcm(CS4231 cs, SINT32 *pcm, UINT count) { | 
 |  |  | 
| UINT    pos; | if ((cs->reg.iface & 1) && (count)) { | 
|  | (*cs4231fn[cs->reg.datafmt >> 4])(cs, pcm, count); | 
| count = min(count, cs->bufsize); |  | 
| if (count) { |  | 
| cs->bufsize -= count; |  | 
| pos = cs->readpos; |  | 
| do { |  | 
| pcm[0] += (*(SINT16 *)(cs->buffer + pos + 0)) >> 1; |  | 
| pcm[1] += (*(SINT16 *)(cs->buffer + pos + 2)) >> 1; |  | 
| pcm += 2; |  | 
| pos = (pos + 4) & (CS4231_BUFBYTES - 1); |  | 
| } while(--count); |  | 
| cs->readpos = pos; |  | 
 | } | } | 
 | } | } | 
 |  |  |