|
|
| version 1.1, 2003/10/16 17:58:08 | version 1.7, 2004/03/29 14:19:25 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "memory.h" | #include "cpucore.h" |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "sound.h" | #include "sound.h" |
| #include "fmboard.h" | #include "fmboard.h" |
| // ---- 補完くらいしようよ… | extern CS4231CFG cs4231cfg; |
| BYTE cs4231_nodecode(void) { | |
| return(0); | static void SOUNDCALL pcm8m(CS4231 cs, SINT32 *pcm, UINT count) { |
| } | |
| static BYTE cs4231_pcm8s(void) { | |
| SINT32 leng; | UINT leng; |
| UINT indatas; | UINT32 pos12; |
| UINT32 addr; | SINT32 fract; |
| UINT32 ctime; | UINT samppos; |
| UINT wpos; | const BYTE *ptr1; |
| const BYTE *ptr2; | |
| leng = dmac.dmach[0].leng.w; | SINT32 samp1; |
| if ((leng >= 2) && (cs4231.bufsize < CS4231_BUFFERS)) { | SINT32 samp2; |
| indatas = cs4231.bufsize; | |
| ctime = cs4231.curtime; | leng = cs->bufdatas >> 0; |
| wpos = cs4231.writepos; | if (!leng) { |
| addr = dmac.dmach[0].adrs.d; | return; |
| do { | |
| while(ctime < cs4231.step) { | |
| ctime += opna_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: | |
| dmac.dmach[0].leng.w = leng; | |
| dmac.dmach[0].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 BYTE cs4231_pcm8m(void) { | 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 = dmac.dmach[0].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 = dmac.dmach[0].adrs.d; | pos12 += cs->step12; |
| do { | } while(--count); |
| while(ctime < cs4231.step) { | |
| ctime += opna_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 BYTE *ptr1; |
| wpos = (wpos + 4) & (CS4231_BUFBYTES - 1); | const BYTE *ptr2; |
| indatas++; | SINT32 samp1; |
| } while(indatas < CS4231_BUFFERS); | SINT32 samp2; |
| p8m_stop: | leng = cs->bufdatas >> 1; |
| dmac.dmach[0].leng.w = leng; | if (!leng) { |
| dmac.dmach[0].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 BYTE cs4231_pcm16s(void) { | 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 = dmac.dmach[0].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 = dmac.dmach[0].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 += opna_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 BYTE *ptr1; |
| indatas++; | const BYTE *ptr2; |
| } while(indatas < CS4231_BUFFERS); | SINT32 samp1; |
| SINT32 samp2; | |
| p16s_stop: | |
| dmac.dmach[0].leng.w = leng; | leng = cs->bufdatas >> 1; |
| dmac.dmach[0].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 BYTE cs4231_pcm16m(void) { | 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 = dmac.dmach[0].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 = dmac.dmach[0].adrs.d; | pos12 += cs->step12; |
| do { | } while(--count); |
| while(ctime < cs4231.step) { | |
| ctime += opna_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 BYTE *ptr1; |
| *(UINT32 *)(cs4231.buffer + wpos) = *(UINT32 *)cs4231.pcmdata, | const BYTE *ptr2; |
| wpos = (wpos + 4) & (CS4231_BUFBYTES - 1); | SINT32 samp1; |
| indatas++; | SINT32 samp2; |
| } while(indatas < CS4231_BUFFERS); | |
| leng = cs->bufdatas >> 2; | |
| p16m_stop: | if (!leng) { |
| dmac.dmach[0].leng.w = leng; | return; |
| dmac.dmach[0].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; | |
| } | } |
| } | } |