DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/snd_pc98/cbus/boardx2.c
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