| version 1.4, 2003/12/08 00:55:33 | version 1.8, 2004/03/29 14:19:25 | 
| Line 1 | Line 1 | 
 | #include        "compiler.h" | #include        "compiler.h" | 
 |  | #include        "cpucore.h" | 
 | #include        "pccore.h" | #include        "pccore.h" | 
 | #include        "iocore.h" | #include        "iocore.h" | 
 | #include        "sound.h" | #include        "sound.h" | 
| Line 7 | Line 8 | 
 |  |  | 
 | CS4231CFG       cs4231cfg; | CS4231CFG       cs4231cfg; | 
 |  |  | 
 |  | enum { | 
 |  | CS4231REG_LINPUT        = 0x00, | 
 |  | CS4231REG_RINPUT        = 0x01, | 
 |  | CS4231REG_AUX1L         = 0x02, | 
 |  | CS4231REG_AUX1R         = 0x03, | 
 |  | CS4231REG_AUX2L         = 0x04, | 
 |  | CS4231REG_AUX2R         = 0x05, | 
 |  | CS4231REG_LOUTPUT       = 0x06, | 
 |  | CS4231REG_ROUTPUT       = 0x07, | 
 |  | CS4231REG_PLAYFMT       = 0x08, | 
 |  | CS4231REG_INTERFACE     = 0x09, | 
 |  | CS4231REG_PINCTRL       = 0x0a, | 
 |  | CS4231REG_TESTINIT      = 0x0b, | 
 |  | CS4231REG_MISCINFO      = 0x0c, | 
 |  | CS4231REG_LOOPBACK      = 0x0d, | 
 |  | CS4231REG_PLAYCNTM      = 0x0e, | 
 |  | CS4231REG_PLAYCNTL      = 0x0f, | 
 |  |  | 
 |  | CS4231REG_FEATURE1      = 0x10, | 
 |  | CS4231REG_FEATURE2      = 0x11, | 
 |  | CS4231REG_LLINEIN       = 0x12, | 
 |  | CS4231REG_RLINEIN       = 0x13, | 
 |  | CS4231REG_TIMERL        = 0x14, | 
 |  | CS4231REG_TIMERH        = 0x15, | 
 |  | CS4231REG_IRQSTAT       = 0x18, | 
 |  | CS4231REG_VERSION       = 0x19, | 
 |  | CS4231REG_MONOCTRL      = 0x1a, | 
 |  | CS4231REG_RECFMT        = 0x1c, | 
 |  | CS4231REG_PLAYFREQ      = 0x1d, | 
 |  | CS4231REG_RECCNTM       = 0x1e, | 
 |  | CS4231REG_RECCNTL       = 0x1f | 
 |  | }; | 
 |  |  | 
 |  |  | 
 |  | static const UINT32 cs4231xtal64[2] = {24576000/64, 16934400/64}; | 
 |  |  | 
 |  | static const UINT8 cs4231cnt64[8] = { | 
 |  | 3072/64,        //  8000/ 5510 | 
 |  | 1536/64,        // 16000/11025 | 
 |  | 896/64,        // 27420/18900 | 
 |  | 768/64,        // 32000/22050 | 
 |  | 448/64,        // 54840/37800 | 
 |  | 384/64,        // 64000/44100 | 
 |  | 512/64,        // 48000/33075 | 
 |  | 2560/64};       //  9600/ 6620 | 
 |  |  | 
| static const UINT16 cs4231samprate[] = { | //    640:441 | 
| 8000,   5510,  16000,  11025, |  | 
| 27420,  18900,  32000,  22050, |  | 
| 54840,  37800,  64000,  44100, |  | 
| 48000,  33075,   9600,   6620}; |  | 
|  |  | 
| static const BYTE dmach[] =  {0xff, 0x00, 0x01, 0x03, 0xff, 0xff, 0xff, 0xff}; |  | 
| static const BYTE dmairq[] = {0xff, 0x03, 0x06, 0x0a, 0x0c, 0xff, 0xff, 0xff}; |  | 
 |  |  | 
 |  |  | 
 | void cs4231_initialize(UINT rate) { | void cs4231_initialize(UINT rate) { | 
| Line 28  void cs4231_setvol(UINT vol) { | Line 67  void cs4231_setvol(UINT vol) { | 
 | (void)vol; | (void)vol; | 
 | } | } | 
 |  |  | 
 |  |  | 
 | void cs4231_dma(NEVENTITEM item) { | void cs4231_dma(NEVENTITEM item) { | 
 |  |  | 
| REG8    ret; | DMACH   dmach; | 
|  | UINT    rem; | 
|  | UINT    pos; | 
|  | UINT    size; | 
|  | UINT    r; | 
 | SINT32  cnt; | SINT32  cnt; | 
 |  |  | 
 | if (item->flag & NEVENT_SETEVENT) { | if (item->flag & NEVENT_SETEVENT) { | 
| if (dmac.dmach[0].leng.w) { | if (cs4231.dmach != 0xff) { | 
 | sound_sync(); | sound_sync(); | 
| ret = cs4231.proc(); | dmach = dmac.dmach + cs4231.dmach; | 
| if ((ret) && (cs4231.reg.pinctrl & 2)) { | if (cs4231.bufsize > cs4231.bufdatas) { | 
| dmac.dmach[0].leng.w = 0; | rem = cs4231.bufsize - cs4231.bufdatas; | 
| cs4231.intflag = 1; | pos = (cs4231.bufpos + cs4231.bufdatas) & CS4231_BUFMASK; | 
| pic_setirq(0x0c); | size = min(rem, CS4231_BUFFERS - pos); | 
|  | r = dmac_getdatas(dmach, cs4231.buffer + pos, size); | 
|  | rem -= r; | 
|  | cs4231.bufdatas += r; | 
|  | if (r != size) { | 
|  | r = dmac_getdatas(dmach, cs4231.buffer, rem); | 
|  | cs4231.bufdatas += r; | 
|  | } | 
|  | } | 
|  | if ((dmach->leng.w) && (cs4231cfg.rate)) { | 
|  | cnt = pccore.realclock * 16 / cs4231cfg.rate; | 
|  | nevent_set(NEVENT_CS4231, cnt, cs4231_dma, NEVENT_RELATIVE); | 
 | } | } | 
 | } |  | 
 | if (cs4231cfg.rate) { |  | 
 | cnt = pc.realclock * 16 / cs4231cfg.rate; |  | 
 | nevent_set(NEVENT_CS4231, cnt, cs4231_dma, NEVENT_RELATIVE); |  | 
 | } | } | 
 | } | } | 
 | (void)item; | (void)item; | 
 | } | } | 
 |  |  | 
 |  | void cs4231_datasend(REG8 dat) { | 
 |  |  | 
 |  | UINT    pos; | 
 |  |  | 
 |  | if (cs4231.reg.iface & 0x40) {                          // PIO play enable | 
 |  | if (cs4231.bufsize <= cs4231.bufdatas) { | 
 |  | sound_sync(); | 
 |  | } | 
 |  | if (cs4231.bufsize > cs4231.bufdatas) { | 
 |  | pos = (cs4231.bufpos + cs4231.bufdatas) & CS4231_BUFMASK; | 
 |  | cs4231.buffer[pos] = dat; | 
 |  | cs4231.bufdatas++; | 
 |  | } | 
 |  | } | 
 |  | } | 
 |  |  | 
 | REG8 DMACCALL cs4231dmafunc(REG8 func) { | REG8 DMACCALL cs4231dmafunc(REG8 func) { | 
 |  |  | 
 | SINT32  cnt; | SINT32  cnt; | 
| Line 59  REG8 DMACCALL cs4231dmafunc(REG8 func) { | Line 124  REG8 DMACCALL cs4231dmafunc(REG8 func) { | 
 | switch(func) { | switch(func) { | 
 | case DMAEXT_START: | case DMAEXT_START: | 
 | if (cs4231cfg.rate) { | if (cs4231cfg.rate) { | 
| cnt = pc.realclock * 16 / cs4231cfg.rate; | cnt = pccore.realclock * 16 / cs4231cfg.rate; | 
 | nevent_set(NEVENT_CS4231, cnt, cs4231_dma, NEVENT_ABSOLUTE); | nevent_set(NEVENT_CS4231, cnt, cs4231_dma, NEVENT_ABSOLUTE); | 
 | } | } | 
 | break; | break; | 
 |  |  | 
 |  | case DMAEXT_END: | 
 |  | if ((cs4231.reg.pinctrl & 2) && (cs4231.dmairq != 0xff)) { | 
 |  | cs4231.intflag = 1; | 
 |  | pic_setirq(cs4231.dmairq); | 
 |  | } | 
 |  | break; | 
 |  |  | 
 | case DMAEXT_BREAK: | case DMAEXT_BREAK: | 
 | nevent_reset(NEVENT_CS4231); | nevent_reset(NEVENT_CS4231); | 
 | break; | break; | 
| Line 74  REG8 DMACCALL cs4231dmafunc(REG8 func) { | Line 146  REG8 DMACCALL cs4231dmafunc(REG8 func) { | 
 | void cs4231_reset(void) { | void cs4231_reset(void) { | 
 |  |  | 
 | ZeroMemory(&cs4231, sizeof(cs4231)); | ZeroMemory(&cs4231, sizeof(cs4231)); | 
| cs4231.proc = cs4231_nodecode; | cs4231.bufsize = CS4231_BUFFERS; | 
|  | //      cs4231.proc = cs4231_nodecode; | 
 | cs4231.port = 0xffff; | cs4231.port = 0xffff; | 
 | cs4231.dmach = 0xff; | cs4231.dmach = 0xff; | 
 | cs4231.dmairq = 0xff; | cs4231.dmairq = 0xff; | 
| Line 84  void cs4231_update(void) { | Line 157  void cs4231_update(void) { | 
 | } | } | 
 |  |  | 
 |  |  | 
| void cs4231_control(UINT index, REG8 value) { | static void setdataalign(void) { | 
 |  |  | 
| *(((BYTE *)(&cs4231.reg)) + index) = value; | UINT    step; | 
|  |  | 
|  | step = (0 - cs4231.bufpos) & 3; | 
|  | if (step) { | 
|  | cs4231.bufpos += step; | 
|  | cs4231.bufdatas -= min(step, cs4231.bufdatas); | 
|  | } | 
|  | cs4231.bufdatas &= ~3; | 
|  | } | 
|  |  | 
|  | void cs4231_control(UINT index, REG8 dat) { | 
|  |  | 
|  | UINT8   modify; | 
|  | DMACH   dmach; | 
|  |  | 
|  | modify = ((BYTE *)&cs4231.reg)[index] ^ dat; | 
|  | ((BYTE *)&cs4231.reg)[index] = dat; | 
 | switch(index) { | switch(index) { | 
| case 8:                                 // playback data format | case CS4231REG_PLAYFMT: | 
| cs4231.proc = cs4231dec[value >> 4]; | if (modify & 0xf0) { | 
| cs4231.step = cs4231samprate[value & 0x0f]; | setdataalign(); | 
|  | } | 
|  | if (modify & 0x0f) { | 
|  | if (cs4231cfg.rate) { | 
|  | UINT32 r; | 
|  | r = cs4231xtal64[dat & 1] / cs4231cnt64[(dat >> 1) & 7]; | 
|  | TRACEOUT(("samprate = %d", r)); | 
|  | r <<= 12; | 
|  | r /= cs4231cfg.rate; | 
|  | cs4231.step12 = r; | 
|  | TRACEOUT(("step12 = %d", r)); | 
|  | } | 
|  | else { | 
|  | cs4231.step12 = 0; | 
|  | } | 
|  | } | 
 | break; | break; | 
 |  |  | 
| case 9: | case CS4231REG_INTERFACE: | 
| if ((value & 0x5) == 0x5) { | if (modify & 5) { | 
| dmac.dmach[0].ready = 1; | if (cs4231.dmach != 0xff) { | 
| } | dmach = dmac.dmach + cs4231.dmach; | 
| else { | if ((dat & 0x5) == 0x5) { | 
| dmac.dmach[0].ready = 0; | dmach->ready = 1; | 
|  | } | 
|  | else { | 
|  | dmach->ready = 0; | 
|  | } | 
|  | dmac_check(); | 
|  | } | 
|  | if (!(dat & 1)) {               // stop! | 
|  | cs4231.pos12 = 0; | 
|  | } | 
 | } | } | 
 | dmac_check(); |  | 
 | break; | break; | 
 | } | } | 
 | } | } |