DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
src/hardware/snd_pc98/sound/pcm86c.c
00001 #include    "np2glue.h"
00002 //#include      "compiler.h"
00003 //#include      "cpucore.h"
00004 //#include      "pccore.h"
00005 //#include      "iocore.h"
00006 #include        "sound.h"
00007 #include        "fmboard.h"
00008 
00009 
00010 // サンプリングレートに8掛けた物
00011 const UINT pcm86rate8[] = {352800, 264600, 176400, 132300,
00012                                                         88200,  66150,  44010,  33075};
00013 
00014 // 32,24,16,12, 8, 6, 4, 3 - 最少公倍数: 96
00015 //  3, 4, 6, 8,12,16,24,32
00016 
00017 #if 0
00018 static const UINT clk25_128[] = {
00019                                         0x00001bde, 0x00002527, 0x000037bb, 0x00004a4e,
00020                                         0x00006f75, 0x0000949c, 0x0000df5f, 0x00012938};
00021 static const UINT clk20_128[] = {
00022                                         0x000016a4, 0x00001e30, 0x00002d48, 0x00003c60,
00023                                         0x00005a8f, 0x000078bf, 0x0000b57d, 0x0000f17d};
00024 #endif
00025 
00026         PCM86CFG        pcm86cfg;
00027 
00028 
00029 void pcm86gen_initialize(UINT rate) {
00030 
00031         pcm86cfg.rate = rate;
00032 }
00033 
00034 void pcm86gen_setvol(UINT vol) {
00035 
00036         pcm86cfg.vol = vol;
00037         pcm86gen_update();
00038 }
00039 
00040 void pcm86_reset(void) {
00041 
00042         ZeroMemory(&pcm86, sizeof(pcm86));
00043         pcm86.fifosize = 0x80;
00044         pcm86.dactrl = 0x32;
00045         pcm86.stepmask = (1 << 2) - 1;
00046         pcm86.stepbit = 2;
00047         pcm86.stepclock = (pccore.baseclock << 6);
00048         pcm86.stepclock /= 44100;
00049         pcm86.stepclock *= pccore.multiple;
00050         pcm86.rescue = (PCM86_RESCUE * 32) << 2;
00051 }
00052 
00053 void pcm86gen_update(void) {
00054 
00055         pcm86.volume = pcm86cfg.vol * pcm86.vol5;
00056         pcm86_setpcmrate(pcm86.fifo);
00057 }
00058 
00059 void pcm86_setpcmrate(REG8 val) {
00060 
00061         SINT32  rate;
00062 
00063         rate = pcm86rate8[val & 7];
00064         pcm86.stepclock = (pccore.baseclock << 6);
00065         pcm86.stepclock /= rate;
00066         pcm86.stepclock *= (pccore.multiple << 3);
00067         if (pcm86cfg.rate) {
00068                 pcm86.div = (rate << (PCM86_DIVBIT - 3)) / pcm86cfg.rate;
00069                 pcm86.div2 = (pcm86cfg.rate << (PCM86_DIVBIT + 3)) / rate;
00070         }
00071 }
00072 
00073 void pcm86_cb(NEVENTITEM item) {
00074     (void)item;//UNUSED
00075 #if 0
00076         if (pcm86.reqirq) {
00077                 sound_sync();
00078 //              RECALC_NOWCLKP;
00079                 if (pcm86.virbuf <= pcm86.fifosize) {
00080                         pcm86.reqirq = 0;
00081                         pcm86.irqflag = 1;
00082                         pic_setirq(fmtimer.irq);
00083                 }
00084                 else {
00085                         pcm86_setnextintr();
00086                 }
00087         }
00088         (void)item;
00089 #endif
00090 }
00091 
00092 void pcm86_setnextintr(void) {
00093 #if 0
00094         SINT32  cnt;
00095         SINT32  clk;
00096 
00097         if (pcm86.fifo & 0x80) {
00098                 cnt = pcm86.virbuf - pcm86.fifosize;
00099                 if (cnt > 0) {
00100                         cnt += pcm86.stepmask;
00101                         cnt >>= pcm86.stepbit;
00102 //                      cnt += 4;                                                               // ちょっと延滞させる
00103                         // ここで clk = pccore.realclock * cnt / 86pcm_rate
00104                         // clk = ((pccore.baseclock / 86pcm_rate) * cnt) * pccore.multiple
00105                         if (pccore.cpumode & CPUMODE_8MHZ) {
00106                                 clk = clk20_128[pcm86.fifo & 7];
00107                         }
00108                         else {
00109                                 clk = clk25_128[pcm86.fifo & 7];
00110                         }
00111                         // cntは最大 8000h で 32bitで収まるように…
00112                         clk *= cnt;
00113                         clk >>= 7;
00114 //                      clk++;                                          // roundup
00115                         clk *= pccore.multiple;
00116                         nevent_set(NEVENT_86PCM, clk, pcm86_cb, NEVENT_ABSOLUTE);
00117                 }
00118         }
00119 #endif
00120 }
00121 
00122 void SOUNDCALL pcm86gen_checkbuf(void) {
00123 #if 0
00124         long    bufs;
00125         UINT32  past;
00126 
00127         past = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
00128         past <<= 6;
00129         past -= pcm86.lastclock;
00130         if (past >= pcm86.stepclock) {
00131                 past = past / pcm86.stepclock;
00132                 pcm86.lastclock += (past * pcm86.stepclock);
00133                 RECALC_NOWCLKWAIT(past);
00134         }
00135 
00136         bufs = pcm86.realbuf - pcm86.virbuf;
00137         if (bufs < 0) {                                                                 // 処理落ちてる…
00138                 bufs &= ~3;
00139                 pcm86.virbuf += bufs;
00140                 if (pcm86.virbuf <= pcm86.fifosize) {
00141                         pcm86.reqirq = 0;
00142                         pcm86.irqflag = 1;
00143                         pic_setirq(fmtimer.irq);
00144                 }
00145                 else {
00146                         pcm86_setnextintr();
00147                 }
00148         }
00149         else {
00150                 bufs -= PCM86_EXTBUF;
00151                 if (bufs > 0) {
00152                         bufs &= ~3;
00153                         pcm86.realbuf -= bufs;
00154                         pcm86.readpos += bufs;
00155                 }
00156         }
00157 #endif
00158 }
00159 
00160 
00161 BOOL pcm86gen_intrq(void) {
00162 
00163         if (pcm86.irqflag) {
00164                 return(TRUE);
00165         }
00166         if (pcm86.fifo & 0x20) {
00167                 sound_sync();
00168                 if ((pcm86.reqirq) && (pcm86.virbuf <= pcm86.fifosize)) {
00169                         pcm86.reqirq = 0;
00170                         pcm86.irqflag = 1;
00171                         return(TRUE);
00172                 }
00173         }
00174         return(FALSE);
00175 }
00176