DOSBox-X
|
00001 #include "compiler.h" 00002 #include "pccore.h" 00003 #include "iocore.h" 00004 #include "cbuscore.h" 00005 #include "boardpx.h" 00006 #include "sound.h" 00007 #include "fmboard.h" 00008 #include "s98.h" 00009 #include "pcm86io.h" 00010 00011 #if defined(SUPPORT_PX) 00012 00013 static void IOOUTCALL spb_o188(UINT port, REG8 dat) { 00014 00015 opn.addr = dat; 00016 opn.data = dat; 00017 (void)port; 00018 } 00019 00020 static void IOOUTCALL spb_o18a(UINT port, REG8 dat) { 00021 00022 UINT addr; 00023 00024 opn.data = dat; 00025 addr = opn.addr; 00026 if (addr >= 0x100) { 00027 return; 00028 } 00029 // S98_put(NORMAL2608, addr, dat); 00030 if (addr < 0x10) { 00031 if (addr != 0x0e) { 00032 psggen_setreg(&psg1, addr, dat); 00033 } 00034 } 00035 else { 00036 if (addr < 0x20) { 00037 rhythm_setreg(&rhythm, addr, dat); 00038 } 00039 else if (addr < 0x30) { 00040 if (addr == 0x28) { 00041 if ((dat & 0x0f) < 3) { 00042 opngen_keyon(dat & 0x0f, dat); 00043 } 00044 else if (((dat & 0x0f) != 3) && 00045 ((dat & 0x0f) < 7)) { 00046 opngen_keyon((dat & 0x0f) - 1, dat); 00047 } 00048 } 00049 else { 00050 fmtimer_setreg(addr, dat); 00051 if (addr == 0x27) { 00052 opnch[2].extop = dat & 0xc0; 00053 } 00054 } 00055 } 00056 else if (addr < 0xc0) { 00057 opngen_setreg(0, addr, dat); 00058 } 00059 opn.reg[addr] = dat; 00060 } 00061 (void)port; 00062 } 00063 00064 static void IOOUTCALL spb_o18c(UINT port, REG8 dat) { 00065 00066 opn.addr = dat + 0x100; 00067 opn.data = dat; 00068 (void)port; 00069 } 00070 00071 static void IOOUTCALL spb_o18e(UINT port, REG8 dat) { 00072 00073 UINT addr; 00074 00075 opn.data = dat; 00076 addr = opn.addr - 0x100; 00077 if (addr >= 0x100) { 00078 return; 00079 } 00080 // S98_put(EXTEND2608, addr, dat); 00081 opn.reg[addr + 0x100] = dat; 00082 if (addr >= 0x30) { 00083 opngen_setreg(3, addr, dat); 00084 } 00085 else if (addr < 0x12) { 00086 adpcm_setreg(&adpcm, addr, dat); 00087 } 00088 (void)port; 00089 } 00090 00091 static REG8 IOINPCALL spb_i188(UINT port) { 00092 00093 (void)port; 00094 return((fmtimer.status & 3) | adpcm_status(&adpcm)); 00095 } 00096 00097 static REG8 IOINPCALL spb_i18a(UINT port) { 00098 00099 UINT addr; 00100 00101 addr = opn.addr; 00102 if (addr == 0x0e) { 00103 return(fmboard_getjoy(&psg1)); 00104 } 00105 else if (addr < 0x10) { 00106 return(psggen_getreg(&psg1, addr)); 00107 } 00108 else if (addr == 0xff) { 00109 return(1); 00110 } 00111 else { 00112 (void)port; 00113 return(opn.data); 00114 } 00115 } 00116 00117 static REG8 IOINPCALL spb_i18e(UINT port) { 00118 00119 UINT addr; 00120 00121 addr = opn.addr - 0x100; 00122 if (addr == 0x08) { 00123 return(adpcm_readsample(&adpcm)); 00124 } 00125 else if (addr == 0x0f) { 00126 return(opn.reg[addr + 0x100]); 00127 } 00128 else { 00129 (void)port; 00130 return(opn.data); 00131 } 00132 } 00133 00134 00135 static void IOOUTCALL spb_o088(UINT port, REG8 dat) { 00136 00137 opn2.addr = dat; 00138 opn2.data = dat; 00139 (void)port; 00140 } 00141 00142 static void IOOUTCALL spb_o08a(UINT port, REG8 dat) { 00143 00144 UINT addr; 00145 00146 opn2.data = dat; 00147 addr = opn2.addr; 00148 if (addr >= 0x100) { 00149 return; 00150 } 00151 // S98_put(NORMAL2608, addr, dat); 00152 if (addr < 0x10) { 00153 if (addr != 0x0e) { 00154 psggen_setreg(&psg2, addr, dat); 00155 } 00156 } 00157 else { 00158 if (addr < 0x20) { 00159 rhythm_setreg(&rhythm2, addr, dat); 00160 } 00161 else if (addr < 0x30) { 00162 if (addr == 0x28) { 00163 if ((dat & 0x0f) < 3) { 00164 opngen_keyon((dat & 0x0f) + 12, dat); 00165 } 00166 else if (((dat & 0x0f) != 3) && 00167 ((dat & 0x0f) < 7)) { 00168 opngen_keyon((dat & 0x0f) + 11, dat); 00169 } 00170 } 00171 else { 00172 fmtimer_setreg(addr, dat); 00173 if (addr == 0x27) { 00174 opnch[14].extop = dat & 0xc0; 00175 } 00176 } 00177 } 00178 else if (addr < 0xc0) { 00179 opngen_setreg(12, addr, dat); 00180 } 00181 opn2.reg[addr] = dat; 00182 } 00183 (void)port; 00184 } 00185 00186 static void IOOUTCALL spb_o08c(UINT port, REG8 dat) { 00187 00188 opn2.addr = dat + 0x100; 00189 opn2.data = dat; 00190 (void)port; 00191 } 00192 00193 static void IOOUTCALL spb_o08e(UINT port, REG8 dat) { 00194 00195 UINT addr; 00196 00197 opn.data = dat; 00198 addr = opn2.addr - 0x100; 00199 if (addr >= 0x100) { 00200 return; 00201 } 00202 // S98_put(EXTEND2608, addr, dat); 00203 opn2.reg[addr + 0x100] = dat; 00204 if (addr >= 0x30) { 00205 opngen_setreg(15, addr, dat); 00206 } 00207 else if (addr < 0x12) { 00208 adpcm_setreg(&adpcm2, addr, dat); 00209 } 00210 (void)port; 00211 } 00212 00213 static REG8 IOINPCALL spb_i088(UINT port) { 00214 00215 (void)port; 00216 return((fmtimer.status & 3) | adpcm_status(&adpcm2)); 00217 } 00218 00219 static REG8 IOINPCALL spb_i08a(UINT port) { 00220 00221 UINT addr; 00222 00223 addr = opn2.addr; 00224 if (addr == 0x0e) { 00225 return(fmboard_getjoy(&psg2)); 00226 } 00227 else if (addr < 0x10) { 00228 return(psggen_getreg(&psg2, addr)); 00229 } 00230 else if (addr == 0xff) { 00231 return(1); 00232 } 00233 else { 00234 (void)port; 00235 return(opn2.data); 00236 } 00237 } 00238 00239 static REG8 IOINPCALL spb_i08e(UINT port) { 00240 00241 UINT addr; 00242 00243 addr = opn2.addr - 0x100; 00244 if (addr == 0x08) { 00245 return(adpcm_readsample(&adpcm2)); 00246 } 00247 else if (addr == 0x0f) { 00248 return(opn2.reg[addr + 0x100]); 00249 } 00250 else 00251 { 00252 (void)port; 00253 return(opn2.data); 00254 } 00255 } 00256 00257 00258 00259 static void IOOUTCALL p86_o288(UINT port, REG8 dat) { 00260 00261 opn3.addr = dat; 00262 opn3.data = dat; 00263 (void)port; 00264 } 00265 00266 static void IOOUTCALL p86_o28a(UINT port, REG8 dat) { 00267 00268 UINT addr; 00269 00270 opn.data = dat; 00271 addr = opn.addr; 00272 if (addr >= 0x100) { 00273 return; 00274 } 00275 // S98_put(NORMAL2608, addr, dat); 00276 if (addr < 0x10) { 00277 if (addr != 0x0e) { 00278 psggen_setreg(&psg3, addr, dat); 00279 } 00280 } 00281 else { 00282 if (addr < 0x20) { 00283 rhythm_setreg(&rhythm3, addr, dat); 00284 } 00285 else if (addr < 0x30) { 00286 if (addr == 0x28) { 00287 if ((dat & 0x0f) < 3) { 00288 opngen_keyon((dat & 0x0f) + 24, dat); 00289 } 00290 else if (((dat & 0x0f) != 3) && 00291 ((dat & 0x0f) < 7)) { 00292 opngen_keyon((dat & 0x0f) + 23, dat); 00293 } 00294 } 00295 else { 00296 fmtimer_setreg(addr, dat); 00297 if (addr == 0x27) { 00298 opnch[26].extop = dat & 0xc0; 00299 } 00300 } 00301 } 00302 else if (addr < 0xc0) { 00303 opngen_setreg(24, addr, dat); 00304 } 00305 opn3.reg[addr] = dat; 00306 } 00307 (void)port; 00308 } 00309 00310 static void IOOUTCALL p86_o28c(UINT port, REG8 dat) { 00311 00312 opn3.addr = dat + 0x100; 00313 opn3.data = dat; 00314 (void)port; 00315 } 00316 00317 static void IOOUTCALL p86_o28e(UINT port, REG8 dat) { 00318 00319 UINT addr; 00320 00321 opn3.data = dat; 00322 addr = opn3.addr - 0x100; 00323 if (addr >= 0x100) { 00324 return; 00325 } 00326 // S98_put(EXTEND2608, addr, dat); 00327 opn3.reg[addr + 0x100] = dat; 00328 if (addr >= 0x30) { 00329 opngen_setreg(27, addr, dat); 00330 } 00331 else if (addr < 0x12) { 00332 adpcm_setreg(&adpcm3, addr, dat); 00333 } 00334 (void)port; 00335 } 00336 00337 static REG8 IOINPCALL p86_i288(UINT port) { 00338 00339 (void)port; 00340 return((fmtimer.status & 3) | adpcm_status(&adpcm3)); 00341 } 00342 00343 static REG8 IOINPCALL p86_i28a(UINT port) { 00344 00345 UINT addr; 00346 00347 addr = opn.addr; 00348 if (addr == 0x0e) { 00349 return(fmboard_getjoy(&psg3)); 00350 } 00351 else if (addr < 0x10) { 00352 return(psggen_getreg(&psg3, addr)); 00353 } 00354 else if (addr == 0xff) { 00355 return(1); 00356 } 00357 else { 00358 (void)port; 00359 return(opn3.data); 00360 } 00361 } 00362 00363 static REG8 IOINPCALL p86_i28e(UINT port) { 00364 00365 UINT addr; 00366 00367 addr = opn3.addr - 0x100; 00368 if (addr == 0x08) { 00369 return(adpcm_readsample(&adpcm3)); 00370 } 00371 else if (addr == 0x0f) { 00372 return(opn3.reg[addr + 0x100]); 00373 } 00374 else { 00375 (void)port; 00376 return(opn3.data); 00377 } 00378 } 00379 00380 00381 // ---- spark board 00382 00383 static void IOOUTCALL spr_o588(UINT port, REG8 dat) { 00384 00385 opn.addr2 = dat; 00386 // opn.data2 = dat; 00387 (void)port; 00388 } 00389 00390 static void IOOUTCALL spr_o58a(UINT port, REG8 dat) { 00391 00392 UINT addr; 00393 00394 // opn.data2 = dat; 00395 addr = opn.addr2; 00396 if (addr >= 0x100) { 00397 return; 00398 } 00399 if (addr < 0x30) { 00400 if (addr == 0x28) { 00401 if ((dat & 0x0f) < 3) { 00402 opngen_keyon((dat & 0x0f) + 6, dat); 00403 } 00404 else if (((dat & 0x0f) != 3) && 00405 ((dat & 0x0f) < 7)) { 00406 opngen_keyon((dat & 0x0f) + 5, dat); 00407 } 00408 } 00409 else { 00410 if (addr == 0x27) { 00411 opnch[8].extop = dat & 0xc0; 00412 } 00413 } 00414 } 00415 else if (addr < 0xc0) { 00416 opngen_setreg(6, addr, dat); 00417 } 00418 opn.reg[addr + 0x200] = dat; 00419 (void)port; 00420 } 00421 00422 static void IOOUTCALL spr_o58c(UINT port, REG8 dat) { 00423 00424 opn.addr2 = dat + 0x100; 00425 // opn.data2 = dat; 00426 (void)port; 00427 } 00428 00429 static void IOOUTCALL spr_o58e(UINT port, REG8 dat) { 00430 00431 UINT addr; 00432 00433 // opn.data2 = dat; 00434 addr = opn.addr2 - 0x100; 00435 if (addr >= 0x100) { 00436 return; 00437 } 00438 opn.reg[addr + 0x300] = dat; 00439 if (addr >= 0x30) { 00440 opngen_setreg(9, addr, dat); 00441 } 00442 (void)port; 00443 } 00444 00445 static REG8 IOINPCALL spr_i588(UINT port) { 00446 00447 (void)port; 00448 return(fmtimer.status); 00449 } 00450 00451 static REG8 IOINPCALL spr_i58a(UINT port) { 00452 00453 UINT addr; 00454 00455 addr = opn.addr2; 00456 if ((addr >= 0x20) && (addr < 0xff)) { 00457 return(opn.reg[addr + 0x200]); 00458 } 00459 else if (addr == 0xff) { 00460 return(0); 00461 } 00462 else { 00463 (void)port; 00464 // return(opn.data2); 00465 return(0xff); 00466 } 00467 } 00468 00469 static REG8 IOINPCALL spr_i58c(UINT port) { 00470 00471 (void)port; 00472 return(fmtimer.status & 3); 00473 } 00474 00475 static REG8 IOINPCALL spr_i58e(UINT port) { 00476 00477 UINT addr; 00478 00479 addr = opn.addr2; 00480 if (addr < 0x100) { 00481 return(opn.reg[addr + 0x200]); 00482 } 00483 else { 00484 (void)port; 00485 // return(opn.data2); 00486 return(0xff); 00487 } 00488 } 00489 00490 00491 static void IOOUTCALL spr_o488(UINT port, REG8 dat) { 00492 00493 opn2.addr2 = dat; 00494 // opn2.data2 = dat; 00495 (void)port; 00496 } 00497 00498 static void IOOUTCALL spr_o48a(UINT port, REG8 dat) { 00499 00500 UINT addr; 00501 00502 // opn2.data2 = dat; 00503 addr = opn2.addr2; 00504 if (addr >= 0x100) { 00505 return; 00506 } 00507 if (addr < 0x30) { 00508 if (addr == 0x28) { 00509 if ((dat & 0x0f) < 3) { 00510 opngen_keyon((dat & 0x0f) + 18, dat); 00511 } 00512 else if (((dat & 0x0f) != 3) && 00513 ((dat & 0x0f) < 7)) { 00514 opngen_keyon((dat & 0x0f) + 17, dat); 00515 } 00516 } 00517 else { 00518 if (addr == 0x27) { 00519 opnch[20].extop = dat & 0xc0; 00520 } 00521 } 00522 } 00523 else if (addr < 0xc0) { 00524 opngen_setreg(18, addr, dat); 00525 } 00526 opn2.reg[addr + 0x200] = dat; 00527 (void)port; 00528 } 00529 00530 static void IOOUTCALL spr_o48c(UINT port, REG8 dat) { 00531 00532 opn2.addr2 = dat + 0x100; 00533 // opn2.data2 = dat; 00534 (void)port; 00535 } 00536 00537 static void IOOUTCALL spr_o48e(UINT port, REG8 dat) { 00538 00539 UINT addr; 00540 00541 // opn.data2 = dat; 00542 addr = opn2.addr2 - 0x100; 00543 if (addr >= 0x100) { 00544 return; 00545 } 00546 opn2.reg[addr + 0x300] = dat; 00547 if (addr >= 0x30) { 00548 opngen_setreg(21, addr, dat); 00549 } 00550 (void)port; 00551 } 00552 00553 static REG8 IOINPCALL spr_i488(UINT port) { 00554 00555 (void)port; 00556 return(fmtimer.status); 00557 } 00558 00559 static REG8 IOINPCALL spr_i48a(UINT port) { 00560 00561 UINT addr; 00562 00563 addr = opn2.addr2; 00564 if ((addr >= 0x20) && (addr < 0xff)) { 00565 return(opn2.reg[addr + 0x200]); 00566 } 00567 else if (addr == 0xff) { 00568 return(0); 00569 } 00570 else { 00571 (void)port; 00572 // return(opn2.data2); 00573 return(0xff); 00574 } 00575 } 00576 00577 static REG8 IOINPCALL spr_i48c(UINT port) { 00578 00579 (void)port; 00580 return(fmtimer.status & 3); 00581 } 00582 00583 static REG8 IOINPCALL spr_i48e(UINT port) { 00584 00585 UINT addr; 00586 00587 addr = opn2.addr2; 00588 if (addr < 0x100) { 00589 return(opn2.reg[addr + 0x200]); 00590 } 00591 else { 00592 (void)port; 00593 // return(opn2.data2); 00594 return(0xff); 00595 } 00596 } 00597 00598 00599 // ---- 00600 00601 static const IOOUT spb_o[4] = { 00602 spb_o188, spb_o18a, spb_o18c, spb_o18e}; 00603 00604 static const IOINP spb_i[4] = { 00605 spb_i188, spb_i18a, spb_i188, spb_i18e}; 00606 00607 static const IOOUT spb_o2[4] = { 00608 spb_o088, spb_o08a, spb_o08c, spb_o08e}; 00609 00610 static const IOINP spb_i2[4] = { 00611 spb_i088, spb_i08a, spb_i088, spb_i08e}; 00612 00613 static const IOOUT p86_o3[4] = { 00614 p86_o288, p86_o28a, p86_o28c, p86_o28e}; 00615 00616 static const IOINP p86_i3[4] = { 00617 p86_i288, p86_i28a, p86_i288, p86_i28e}; 00618 00619 // ---- 00620 00621 static const IOOUT spr_o[4] = { 00622 spr_o588, spr_o58a, spr_o58c, spr_o58e}; 00623 00624 static const IOINP spr_i[4] = { 00625 spr_i588, spr_i58a, spr_i58c, spr_i58e}; 00626 00627 static const IOOUT spr_o2[4] = { 00628 spr_o488, spr_o48a, spr_o48c, spr_o48e}; 00629 00630 static const IOINP spr_i2[4] = { 00631 spr_i488, spr_i48a, spr_i48c, spr_i48e}; 00632 00633 void boardpx1_reset(const NP2CFG *pConfig) { 00634 00635 fmtimer_reset(pConfig->spbopt & 0xc0); 00636 opn.reg[0x2ff] = 0; 00637 opn.channels = 12; 00638 opn2.reg[0x2ff] = 0; 00639 opn2.channels = 12; 00640 opngen_setcfg(24, OPN_STEREO | 0x00ffffff); 00641 soundrom_loadex(pConfig->spbopt & 7, OEMTEXT("SPB")); 00642 opn.base = (pConfig->spbopt & 0x10)?0x000:0x100; 00643 } 00644 00645 void boardpx1_bind(void) { 00646 00647 fmboard_fmrestore(0, 0); 00648 fmboard_fmrestore(3, 1); 00649 fmboard_fmrestore(6, 2); 00650 fmboard_fmrestore(9, 3); 00651 fmboard_fmrestore2(&opn2, 12, 0); 00652 fmboard_fmrestore2(&opn2, 15, 1); 00653 fmboard_fmrestore2(&opn2, 18, 2); 00654 fmboard_fmrestore2(&opn2, 21, 3); 00655 psggen_restore(&psg1); 00656 psggen_restore(&psg2); 00657 fmboard_rhyrestore(&rhythm, 0); 00658 fmboard_rhyrestore2(&opn2, &rhythm2, 0); 00659 sound_streamregist(&opngen, (SOUNDCB)opngen_getpcmvr); 00660 sound_streamregist(&psg1, (SOUNDCB)psggen_getpcm); 00661 sound_streamregist(&psg2, (SOUNDCB)psggen_getpcm); 00662 rhythm_bind(&rhythm); 00663 rhythm_bind(&rhythm2); 00664 sound_streamregist(&adpcm, (SOUNDCB)adpcm_getpcm); 00665 sound_streamregist(&adpcm2, (SOUNDCB)adpcm_getpcm); 00666 00667 cbuscore_attachsndex(0x188, spb_o, spb_i); 00668 cbuscore_attachsndex(0x588, spr_o, spr_i); 00669 cbuscore_attachsndex(0x088, spb_o2, spb_i2); 00670 cbuscore_attachsndex(0x488, spr_o2, spr_i2); 00671 } 00672 00673 00674 static void extendchannelx2(REG8 enable) { 00675 00676 opn3.extend = enable; 00677 if (enable) { 00678 opn3.channels = 6; 00679 opngen_setcfg(30, OPN_STEREO | 0x07000000); 00680 } 00681 else { 00682 opn3.channels = 3; 00683 opngen_setcfg(27, OPN_MONORAL | 0x07000000); 00684 rhythm_setreg(&rhythm2, 0x10, 0xff); 00685 } 00686 } 00687 00688 void boardpx2_reset(const NP2CFG *pConfig) { 00689 00690 fmtimer_reset(pConfig->spbopt & 0xc0); 00691 opn.reg[0x2ff] = 0; 00692 opn.channels = 12; 00693 opn2.reg[0x2ff] = 0; 00694 opn2.channels = 12; 00695 opn3.channels = 3; 00696 opngen_setcfg(27, OPN_STEREO | 0x38ffffff); 00697 soundrom_loadex(pConfig->spbopt & 7, OEMTEXT("SPB")); 00698 opn.base = (pConfig->spbopt & 0x10)?0x000:0x100; 00699 fmboard_extreg(extendchannelx2); 00700 } 00701 00702 void boardpx2_bind(void) { 00703 00704 fmboard_fmrestore(0, 0); 00705 fmboard_fmrestore(3, 1); 00706 fmboard_fmrestore(6, 2); 00707 fmboard_fmrestore(9, 3); 00708 fmboard_fmrestore2(&opn2, 12, 0); 00709 fmboard_fmrestore2(&opn2, 15, 1); 00710 fmboard_fmrestore2(&opn2, 18, 2); 00711 fmboard_fmrestore2(&opn2, 21, 3); 00712 fmboard_fmrestore2(&opn3, 24, 0); 00713 fmboard_fmrestore2(&opn3, 27, 1); 00714 psggen_restore(&psg1); 00715 psggen_restore(&psg2); 00716 psggen_restore(&psg3); 00717 fmboard_rhyrestore(&rhythm, 0); 00718 fmboard_rhyrestore2(&opn2, &rhythm2, 0); 00719 fmboard_rhyrestore2(&opn3, &rhythm3, 0); 00720 sound_streamregist(&opngen, (SOUNDCB)opngen_getpcmvr); 00721 sound_streamregist(&psg1, (SOUNDCB)psggen_getpcm); 00722 sound_streamregist(&psg2, (SOUNDCB)psggen_getpcm); 00723 sound_streamregist(&psg3, (SOUNDCB)psggen_getpcm); 00724 rhythm_bind(&rhythm); 00725 rhythm_bind(&rhythm2); 00726 rhythm_bind(&rhythm3); 00727 sound_streamregist(&adpcm, (SOUNDCB)adpcm_getpcm); 00728 sound_streamregist(&adpcm2, (SOUNDCB)adpcm_getpcm); 00729 sound_streamregist(&adpcm3, (SOUNDCB)adpcm_getpcm); 00730 00731 pcm86io_bind(); 00732 00733 cbuscore_attachsndex(0x188, spb_o, spb_i); 00734 cbuscore_attachsndex(0x588, spr_o, spr_i); 00735 cbuscore_attachsndex(0x088, spb_o2, spb_i2); 00736 cbuscore_attachsndex(0x488, spr_o2, spr_i2); 00737 cbuscore_attachsndex(0x288, p86_o3, p86_i3); 00738 } 00739 00740 #endif // defined(SUPPORT_PX) 00741