DOSBox-X
|
00001 #include "compiler.h" 00002 #include "cpucore.h" 00003 #include "pccore.h" 00004 #include "iocore.h" 00005 #include "pcm86io.h" 00006 #include "sound.h" 00007 #include "fmboard.h" 00008 00009 00010 extern PCM86CFG pcm86cfg; 00011 00012 00013 static const UINT8 pcm86bits[] = {1, 1, 1, 2, 0, 0, 0, 1}; 00014 static const SINT32 pcm86rescue[] = {PCM86_RESCUE * 32, PCM86_RESCUE * 24, 00015 PCM86_RESCUE * 16, PCM86_RESCUE * 12, 00016 PCM86_RESCUE * 8, PCM86_RESCUE * 6, 00017 PCM86_RESCUE * 4, PCM86_RESCUE * 3}; 00018 00019 00020 static void IOOUTCALL pcm86_oa460(UINT port, REG8 val) { 00021 00022 // TRACEOUT(("86pcm out %.4x %.2x", port, val)); 00023 pcm86.extfunc = val; 00024 fmboard_extenable((REG8)(val & 1)); 00025 (void)port; 00026 } 00027 00028 static void IOOUTCALL pcm86_oa466(UINT port, REG8 val) { 00029 00030 // TRACEOUT(("86pcm out %.4x %.2x", port, val)); 00031 if ((val & 0xe0) == 0xa0) { 00032 sound_sync(); 00033 pcm86.vol5 = (~val) & 15; 00034 pcm86.volume = pcm86cfg.vol * pcm86.vol5; 00035 } 00036 (void)port; 00037 } 00038 00039 static void IOOUTCALL pcm86_oa468(UINT port, REG8 val) { 00040 00041 REG8 xchgbit; 00042 00043 // TRACEOUT(("86pcm out %.4x %.2x", port, val)); 00044 sound_sync(); 00045 xchgbit = pcm86.fifo ^ val; 00046 // バッファリセット判定 00047 if ((xchgbit & 8) && (val & 8)) { 00048 pcm86.readpos = 0; // バッファリセット 00049 pcm86.wrtpos = 0; 00050 pcm86.realbuf = 0; 00051 pcm86.virbuf = 0; 00052 pcm86.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; 00053 pcm86.lastclock <<= 6; 00054 } 00055 if ((xchgbit & 0x10) && (!(val & 0x10))) { 00056 pcm86.irqflag = 0; 00057 // pcm86.write = 0; 00058 // pcm86.reqirq = 0; 00059 } 00060 // サンプリングレート変更 00061 if (xchgbit & 7) { 00062 pcm86.rescue = pcm86rescue[val & 7] << pcm86.stepbit; 00063 pcm86_setpcmrate(val); 00064 } 00065 #if 1 // これ重大なバグ.... 00066 pcm86.fifo = val; 00067 #else 00068 pcm86.fifo = val & (~0x10); 00069 #endif 00070 if ((xchgbit & 0x80) && (val & 0x80)) { 00071 pcm86.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; 00072 pcm86.lastclock <<= 6; 00073 } 00074 pcm86_setnextintr(); 00075 (void)port; 00076 } 00077 00078 static void IOOUTCALL pcm86_oa46a(UINT port, REG8 val) { 00079 00080 // TRACEOUT(("86pcm out %.4x %.2x", port, val)); 00081 sound_sync(); 00082 if (pcm86.fifo & 0x20) { 00083 #if 1 00084 if (val != 0xff) { 00085 pcm86.fifosize = (UINT16)((val + 1) << 7); 00086 } 00087 else { 00088 pcm86.fifosize = 0x7ffc; 00089 } 00090 #else 00091 if (!val) { 00092 val++; 00093 } 00094 pcm86.fifosize = (WORD)(val) << 7; 00095 #endif 00096 } 00097 else { 00098 pcm86.dactrl = val; 00099 pcm86.stepbit = pcm86bits[(val >> 4) & 7]; 00100 pcm86.stepmask = (1 << pcm86.stepbit) - 1; 00101 pcm86.rescue = pcm86rescue[pcm86.fifo & 7] << pcm86.stepbit; 00102 } 00103 pcm86_setnextintr(); 00104 (void)port; 00105 } 00106 00107 static void IOOUTCALL pcm86_oa46c(UINT port, REG8 val) { 00108 00109 // TRACEOUT(("86pcm out %.4x %.2x", port, val)); 00110 #if 1 00111 if (pcm86.virbuf < PCM86_LOGICALBUF) { 00112 pcm86.virbuf++; 00113 } 00114 pcm86.buffer[pcm86.wrtpos] = val; 00115 pcm86.wrtpos = (pcm86.wrtpos + 1) & PCM86_BUFMSK; 00116 pcm86.realbuf++; 00117 // バッファオーバーフローの監視 00118 if (pcm86.realbuf >= PCM86_REALBUFSIZE) { 00119 #if 1 00120 pcm86.realbuf -= 4; 00121 pcm86.readpos = (pcm86.readpos + 4) & PCM86_BUFMSK; 00122 #else 00123 pcm86.realbuf &= 3; // align4決めウチ 00124 pcm86.realbuf += PCM86_REALBUFSIZE - 4; 00125 #endif 00126 } 00127 // pcm86.write = 1; 00128 pcm86.reqirq = 1; 00129 #else 00130 if (pcm86.virbuf < PCM86_LOGICALBUF) { 00131 pcm86.virbuf++; 00132 pcm86.buffer[pcm86.wrtpos] = val; 00133 pcm86.wrtpos = (pcm86.wrtpos + 1) & PCM86_BUFMSK; 00134 pcm86.realbuf++; 00135 // バッファオーバーフローの監視 00136 if (pcm86.realbuf >= PCM86_REALBUFSIZE) { 00137 pcm86.realbuf &= 3; // align4決めウチ 00138 pcm86.realbuf += PCM86_REALBUFSIZE - 4; 00139 } 00140 // pcm86.write = 1; 00141 pcm86.reqirq = 1; 00142 } 00143 #endif 00144 (void)port; 00145 } 00146 00147 static REG8 IOINPCALL pcm86_ia460(UINT port) { 00148 00149 (void)port; 00150 return(0x40 | (pcm86.extfunc & 1)); 00151 } 00152 00153 static REG8 IOINPCALL pcm86_ia466(UINT port) { 00154 00155 UINT32 past; 00156 UINT32 cnt; 00157 UINT32 stepclock; 00158 REG8 ret; 00159 00160 past = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; 00161 past <<= 6; 00162 past -= pcm86.lastclock; 00163 stepclock = pcm86.stepclock; 00164 if (past >= stepclock) { 00165 cnt = past / stepclock; 00166 pcm86.lastclock += (cnt * stepclock); 00167 past -= cnt * stepclock; 00168 if (pcm86.fifo & 0x80) { 00169 sound_sync(); 00170 RECALC_NOWCLKWAIT(cnt); 00171 } 00172 } 00173 ret = ((past << 1) >= stepclock)?1:0; 00174 if (pcm86.virbuf >= PCM86_LOGICALBUF) { // バッファフル 00175 ret |= 0x80; 00176 } 00177 else if (!pcm86.virbuf) { // バッファ0 00178 ret |= 0x40; // ちと変… 00179 } 00180 (void)port; 00181 // TRACEOUT(("86pcm in %.4x %.2x", port, ret)); 00182 return(ret); 00183 } 00184 00185 static REG8 IOINPCALL pcm86_ia468(UINT port) { 00186 00187 REG8 ret; 00188 00189 ret = pcm86.fifo & (~0x10); 00190 #if 1 00191 if (pcm86gen_intrq()) { 00192 ret |= 0x10; 00193 } 00194 #elif 1 // むしろこう? 00195 if (pcm86.fifo & 0x20) { 00196 sound_sync(); 00197 if (pcm86.virbuf <= pcm86.fifosize) { 00198 if (pcm86.write) { 00199 pcm86.write = 0; 00200 } 00201 else { 00202 ret |= 0x10; 00203 } 00204 } 00205 } 00206 #else 00207 if ((pcm86.write) && (pcm86.fifo & 0x20)) { 00208 // pcm86.write = 0; 00209 sound_sync(); 00210 if (pcm86.virbuf <= pcm86.fifosize) { 00211 pcm86.write = 0; 00212 ret |= 0x10; 00213 } 00214 } 00215 #endif 00216 (void)port; 00217 // TRACEOUT(("86pcm in %.4x %.2x", port, ret)); 00218 return(ret); 00219 } 00220 00221 static REG8 IOINPCALL pcm86_ia46a(UINT port) { 00222 00223 (void)port; 00224 // TRACEOUT(("86pcm in %.4x %.2x", port, pcm86.dactrl)); 00225 return(pcm86.dactrl); 00226 } 00227 00228 static REG8 IOINPCALL pcm86_inpdummy(UINT port) { 00229 00230 (void)port; 00231 return(0); 00232 } 00233 00234 00235 // ---- 00236 00237 void pcm86io_bind(void) { 00238 00239 sound_streamregist(&pcm86, (SOUNDCB)pcm86gen_getpcm); 00240 00241 iocore_attachout(0xa460, pcm86_oa460); 00242 iocore_attachout(0xa466, pcm86_oa466); 00243 iocore_attachout(0xa468, pcm86_oa468); 00244 iocore_attachout(0xa46a, pcm86_oa46a); 00245 iocore_attachout(0xa46c, pcm86_oa46c); 00246 00247 iocore_attachinp(0xa460, pcm86_ia460); 00248 iocore_attachinp(0xa462, pcm86_inpdummy); 00249 iocore_attachinp(0xa464, pcm86_inpdummy); 00250 iocore_attachinp(0xa466, pcm86_ia466); 00251 iocore_attachinp(0xa468, pcm86_ia468); 00252 iocore_attachinp(0xa46a, pcm86_ia46a); 00253 iocore_attachinp(0xa46c, pcm86_inpdummy); 00254 iocore_attachinp(0xa46e, pcm86_inpdummy); 00255 } 00256