DOSBox-X
|
00001 #include "compiler.h" 00002 #include "pccore.h" 00003 #include "iocore.h" 00004 #include "cbuscore.h" 00005 #include "boardx2.h" 00006 #include "pcm86io.h" 00007 #include "sound.h" 00008 #include "fmboard.h" 00009 #include "s98.h" 00010 00011 00012 static void IOOUTCALL opn_o088(UINT port, REG8 dat) { 00013 00014 opn.addr2 = dat; 00015 opn.data2 = dat; 00016 (void)port; 00017 } 00018 00019 static void IOOUTCALL opn_o08a(UINT port, REG8 dat) { 00020 00021 UINT addr; 00022 00023 opn.data2 = dat; 00024 addr = opn.addr2; 00025 if (addr < 0x10) { 00026 if (addr != 0x0e) { 00027 psggen_setreg(&psg1, addr, dat); 00028 } 00029 } 00030 else { 00031 if (addr < 0x30) { 00032 if (addr == 0x28) { 00033 if ((dat & 0x0f) < 3) { 00034 opngen_keyon(dat & 0x0f, dat); 00035 } 00036 } 00037 else { 00038 fmtimer_setreg(addr, dat); 00039 if (addr == 0x27) { 00040 opnch[2].extop = dat & 0xc0; 00041 } 00042 } 00043 } 00044 else if (addr < 0xc0) { 00045 opngen_setreg(0, addr, dat); 00046 } 00047 opn.reg[addr + 0x200] = dat; 00048 } 00049 (void)port; 00050 } 00051 00052 static REG8 IOINPCALL opn_i088(UINT port) { 00053 00054 (void)port; 00055 return(fmtimer.status); 00056 } 00057 00058 static REG8 IOINPCALL opn_i08a(UINT port) { 00059 00060 UINT addr; 00061 00062 addr = opn.addr2; 00063 if (addr == 0x0e) { 00064 return(0xff); 00065 } 00066 if (addr < 0x10) { 00067 return(psggen_getreg(&psg1, addr)); 00068 } 00069 else { 00070 (void)port; 00071 return(opn.data2); 00072 } 00073 } 00074 00075 00076 // ---- 00077 00078 static void IOOUTCALL opna_o188(UINT port, REG8 dat) { 00079 00080 opn.addr = dat; 00081 opn.data = dat; 00082 (void)port; 00083 } 00084 00085 static void IOOUTCALL opna_o18a(UINT port, REG8 dat) { 00086 00087 UINT addr; 00088 00089 opn.data = dat; 00090 addr = opn.addr; 00091 if (addr >= 0x100) { 00092 return; 00093 } 00094 S98_put(NORMAL2608, addr, dat); 00095 if (addr < 0x10) { 00096 if (addr != 0x0e) { 00097 psggen_setreg(&psg2, addr, dat); 00098 } 00099 } 00100 else { 00101 if (addr < 0x20) { 00102 if (opn.extend) { 00103 rhythm_setreg(&rhythm, addr, dat); 00104 } 00105 } 00106 else if (addr < 0x30) { 00107 if (addr == 0x28) { 00108 if ((dat & 0x0f) < 3) { 00109 opngen_keyon((dat & 0x0f) + 3, dat); 00110 } 00111 else if (((dat & 0x0f) != 3) && 00112 ((dat & 0x0f) < 7)) { 00113 opngen_keyon((dat & 0x0f) + 2, dat); 00114 } 00115 } 00116 else { 00117 fmtimer_setreg(addr, dat); 00118 if (addr == 0x27) { 00119 opnch[2].extop = dat & 0xc0; 00120 } 00121 } 00122 } 00123 else if (addr < 0xc0) { 00124 opngen_setreg(3, addr, dat); 00125 } 00126 opn.reg[addr] = dat; 00127 } 00128 (void)port; 00129 } 00130 00131 static void IOOUTCALL opna_o18c(UINT port, REG8 dat) { 00132 00133 if (opn.extend) { 00134 opn.addr = dat + 0x100; 00135 opn.data = dat; 00136 } 00137 (void)port; 00138 } 00139 00140 static void IOOUTCALL opna_o18e(UINT port, REG8 dat) { 00141 00142 UINT addr; 00143 00144 if (!opn.extend) { 00145 return; 00146 } 00147 addr = opn.addr - 0x100; 00148 if (addr >= 0x100) { 00149 return; 00150 } 00151 S98_put(EXTEND2608, addr, dat); 00152 opn.reg[addr + 0x100] = dat; 00153 if (addr >= 0x30) { 00154 opngen_setreg(6, addr, dat); 00155 } 00156 else { 00157 if (addr == 0x10) { 00158 if (!(dat & 0x80)) { 00159 opn.adpcmmask = ~(dat & 0x1c); 00160 } 00161 } 00162 } 00163 (void)port; 00164 } 00165 00166 static REG8 IOINPCALL opna_i188(UINT port) { 00167 00168 (void)port; 00169 return(fmtimer.status); 00170 } 00171 00172 static REG8 IOINPCALL opna_i18a(UINT port) { 00173 00174 UINT addr; 00175 00176 addr = opn.addr; 00177 if (addr == 0x0e) { 00178 return(fmboard_getjoy(&psg2)); 00179 } 00180 else if (addr < 0x10) { 00181 return(psggen_getreg(&psg2, addr)); 00182 } 00183 else if (addr == 0xff) { 00184 return(1); 00185 } 00186 else { 00187 (void)port; 00188 return(opn.data); 00189 } 00190 } 00191 00192 static REG8 IOINPCALL opna_i18c(UINT port) { 00193 00194 if (opn.extend) { 00195 return((fmtimer.status & 3) | (opn.adpcmmask & 8)); 00196 } 00197 (void)port; 00198 return(0xff); 00199 } 00200 00201 static REG8 IOINPCALL opna_i18e(UINT port) { 00202 00203 if (opn.extend) { 00204 UINT addr = opn.addr - 0x100; 00205 if ((addr == 0x08) || (addr == 0x0f)) { 00206 return(opn.reg[addr + 0x100]); 00207 } 00208 return(opn.data); 00209 } 00210 (void)port; 00211 return(0xff); 00212 } 00213 00214 static void extendchannel(REG8 enable) { 00215 00216 opn.extend = enable; 00217 if (enable) { 00218 opn.channels = 9; 00219 opngen_setcfg(9, OPN_STEREO | 0x038); 00220 } 00221 else { 00222 opn.channels = 6; 00223 opngen_setcfg(6, OPN_MONORAL | 0x038); 00224 rhythm_setreg(&rhythm, 0x10, 0xff); 00225 } 00226 } 00227 00228 00229 // ---- 00230 00231 static const IOOUT opn_o[4] = { 00232 opn_o088, opn_o08a, NULL, NULL}; 00233 00234 static const IOINP opn_i[4] = { 00235 opn_i088, opn_i08a, NULL, NULL}; 00236 00237 static const IOOUT opna_o[4] = { 00238 opna_o188, opna_o18a, opna_o18c, opna_o18e}; 00239 00240 static const IOINP opna_i[4] = { 00241 opna_i188, opna_i18a, opna_i18c, opna_i18e}; 00242 00243 00244 void boardx2_reset(const NP2CFG *pConfig) { 00245 00246 fmtimer_reset(0xc0); 00247 opn.channels = 6; 00248 opngen_setcfg(6, OPN_STEREO | 0x1c0); 00249 soundrom_load(0xcc000, OEMTEXT("86")); 00250 fmboard_extreg(extendchannel); 00251 00252 (void)pConfig; 00253 } 00254 00255 void boardx2_bind(void) { 00256 00257 fmboard_fmrestore(0, 2); 00258 fmboard_fmrestore(3, 0); 00259 fmboard_fmrestore(6, 1); 00260 psggen_restore(&psg1); 00261 psggen_restore(&psg2); 00262 fmboard_rhyrestore(&rhythm, 0); 00263 sound_streamregist(&opngen, (SOUNDCB)opngen_getpcm); 00264 sound_streamregist(&psg1, (SOUNDCB)psggen_getpcm); 00265 sound_streamregist(&psg2, (SOUNDCB)psggen_getpcm); 00266 rhythm_bind(&rhythm); 00267 pcm86io_bind(); 00268 cbuscore_attachsndex(0x088, opn_o, opn_i); 00269 cbuscore_attachsndex(0x188, opna_o, opna_i); 00270 } 00271