DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/snd_pc98/sound/opngenc.c
00001 #include    "np2glue.h"
00002 //#include      "compiler.h"
00003 #include        <math.h>
00004 //#include      "pccore.h"
00005 //#include      "iocore.h"
00006 #include        "sound.h"
00007 #include        "fmboard.h"
00008 //#include      "keydisp.h"
00009 
00010 
00011 #define OPM_ARRATE               399128L
00012 #define OPM_DRRATE              5514396L
00013 
00014 #define EG_STEP (96.0 / EVC_ENT)                                        // dB step
00015 #define SC(db)  (SINT32)((db) * ((3.0 / EG_STEP) * (1 << ENV_BITS))) + EC_DECAY
00016 #define D2(v)   (((double)(6 << KF_BITS) * log((double)(v)) / log(2.0)) + 0.5)
00017 #define FMASMSHIFT      (32 - 6 - (OPM_OUTSB + 1 + FMDIV_BITS) + FMVOL_SFTBIT)
00018 #define FREQBASE4096    ((double)OPNA_CLOCK / calcrate / 64)
00019 
00020 
00021         OPNCFG  opncfg;
00022 #ifdef OPNGENX86
00023         char    envshift[EVC_ENT];
00024         char    sinshift[SIN_ENT];
00025 #endif
00026 
00027 
00028 static  SINT32  detunetable[8][32];
00029 static  SINT32  attacktable[94];
00030 static  SINT32  decaytable[94];
00031 
00032 static const SINT32     decayleveltable[16] = {
00033                                         SC( 0),SC( 1),SC( 2),SC( 3),SC( 4),SC( 5),SC( 6),SC( 7),
00034                                         SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)};
00035 static const UINT8 multipletable[] = {
00036                                 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
00037 static const SINT32 nulltable[] = {
00038                                         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00039                                         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
00040 static const UINT8 kftable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};
00041 static const UINT8 dttable[] = {
00042                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00043                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00044                                         0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
00045                                         2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
00046                                         1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
00047                                         5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
00048                                         2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
00049                                         8, 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22};
00050 static const int extendslot[4] = {2, 3, 1, 0};
00051 static const int fmslot[4] = {0, 2, 1, 3};
00052 
00053 
00054 void opngen_initialize(UINT rate) {
00055 
00056         UINT    ratebit;
00057         int             i;
00058         char    sft;
00059         int             j;
00060         double  pom;
00061         long    detune;
00062         double  freq;
00063         UINT32  calcrate;
00064 
00065         if (rate == 44100) {
00066                 ratebit = 0;
00067         }
00068         else if (rate == 22050) {
00069                 ratebit = 1;
00070         }
00071         else {
00072                 ratebit = 2;
00073         }
00074         calcrate = (OPNA_CLOCK / 72) >> ratebit;
00075         opncfg.calc1024 = FMDIV_ENT * 44100 / (OPNA_CLOCK / 72);
00076 
00077         for (i=0; i<EVC_ENT; i++) {
00078 #ifdef OPNGENX86
00079                 sft = ENVTBL_BIT;
00080                 while(sft < (ENVTBL_BIT + 8)) {
00081                         pom = (double)(1 << sft) / pow(10.0, EG_STEP*(EVC_ENT-i)/20.0);
00082                         opncfg.envtable[i] = (long)pom;
00083                         envshift[i] = sft - TL_BITS;
00084                         if (opncfg.envtable[i] >= (1 << (ENVTBL_BIT - 1))) {
00085                                 break;
00086                         }
00087                         sft++;
00088                 }
00089 #else
00090                 pom = (double)(1 << ENVTBL_BIT) / pow(10.0, EG_STEP*(EVC_ENT-i)/20.0);
00091                 opncfg.envtable[i] = (long)pom;
00092 #endif
00093         }
00094         for (i=0; i<SIN_ENT; i++) {
00095 #ifdef OPNGENX86
00096                 char sft;
00097                 sft = SINTBL_BIT;
00098                 while(sft < (SINTBL_BIT + 8)) {
00099                         pom = (double)(1 << sft) * sin(2*PI*i/SIN_ENT);
00100                         opncfg.sintable[i] = (long)pom;
00101                         sinshift[i] = sft;
00102                         if (opncfg.sintable[i] >= (1 << (SINTBL_BIT - 1))) {
00103                                 break;
00104                         }
00105                         if (opncfg.sintable[i] <= -1 * (1 << (SINTBL_BIT - 1))) {
00106                                 break;
00107                         }
00108                         sft++;
00109                 }
00110 #else
00111                 pom = (double)((1 << SINTBL_BIT) - 1) * sin(2*PI*i/SIN_ENT);
00112                 opncfg.sintable[i] = (long)pom;
00113 #endif
00114         }
00115         for (i=0; i<EVC_ENT; i++) {
00116                 pom = pow(((double)(EVC_ENT-1-i)/EVC_ENT), 8) * EVC_ENT;
00117                 opncfg.envcurve[i] = (long)pom;
00118                 opncfg.envcurve[EVC_ENT + i] = i;
00119         }
00120         opncfg.envcurve[EVC_ENT*2] = EVC_ENT;
00121 
00122 //      opmbaserate = (1L << FREQ_BITS) / (rate * x / 44100) * 55466;
00123 //      でも今は x == 55466だから…
00124 
00125 //      ここで FREQ_BITS >= 16が条件
00126         if (rate == 44100) {
00127                 opncfg.ratebit = 0 + (FREQ_BITS - 16);
00128         }
00129         else if (rate == 22050) {
00130                 opncfg.ratebit = 1 + (FREQ_BITS - 16);
00131         }
00132         else {
00133                 opncfg.ratebit = 2 + (FREQ_BITS - 16);
00134         }
00135 
00136         for (i=0; i<4; i++) {
00137                 for (j=0; j<32; j++) {
00138                         detune = dttable[i*32 + j];
00139                         sft = ratebit + (FREQ_BITS - 21);
00140                         if (sft >= 0) {
00141                                 detune <<= sft;
00142                         }
00143                         else {
00144                                 detune >>= (0 - sft);
00145                         }
00146 
00147                         detunetable[i][j]   = detune;
00148                         detunetable[i+4][j] = -detune;
00149                 }
00150         }
00151         for (i=0; i<4; i++) {
00152                 attacktable[i] = decaytable[i] = 0;
00153         }
00154         for (i=4; i<64; i++) {
00155                 freq = (double)(EVC_ENT << ENV_BITS) * FREQBASE4096;
00156                 if (i < 8) {                                                    // 忘れてます。
00157                         freq *= 1.0 + (i & 2) * 0.25;
00158                 }
00159                 else if (i < 60) {
00160                         freq *= 1.0 + (i & 3) * 0.25;
00161                 }
00162                 freq *= (double)(1 << ((i >> 2) - 1));
00163 #if 0
00164                 attacktable[i] = (long)((freq + OPM_ARRATE - 1) / OPM_ARRATE);
00165                 decaytable[i] = (long)((freq + OPM_DRRATE - 1) / OPM_DRRATE);
00166 #else
00167                 attacktable[i] = (long)(freq / OPM_ARRATE);
00168                 decaytable[i] = (long)(freq / OPM_DRRATE);
00169 #endif
00170                 if (attacktable[i] >= EC_DECAY) {
00171                         TRACEOUT(("attacktable %d %d %ld", i, attacktable[i], EC_DECAY));
00172                 }
00173                 if (decaytable[i] >= EC_DECAY) {
00174                         TRACEOUT(("decaytable %d %d %ld", i, decaytable[i], EC_DECAY));
00175                 }
00176         }
00177         attacktable[62] = EC_DECAY - 1;
00178         attacktable[63] = EC_DECAY - 1;
00179         for (i=64; i<94; i++) {
00180                 attacktable[i] = attacktable[63];
00181                 decaytable[i] = decaytable[63];
00182         }
00183 }
00184 
00185 void opngen_setvol(UINT vol) {
00186 
00187         opncfg.fmvol = vol * 5 / 4;
00188 #if defined(OPNGENX86)
00189         opncfg.fmvol <<= FMASMSHIFT;
00190 #endif
00191 }
00192 
00193 void opngen_setVR(REG8 channel, REG8 value) {
00194 
00195         if ((channel & 3) && (value)) {
00196                 opncfg.vr_en = TRUE;
00197                 opncfg.vr_l = (channel & 1)?value:0;
00198                 opncfg.vr_r = (channel & 2)?value:0;
00199         }
00200         else {
00201                 opncfg.vr_en = FALSE;
00202         }
00203 }
00204 
00205 
00206 // ----
00207 
00208 static void set_algorithm(OPNCH *ch) {
00209 
00210         SINT32  *outd;
00211         UINT8   outslot;
00212 
00213         outd = &opngen.outdc;
00214         if (ch->stereo) {
00215                 switch(ch->pan & 0xc0) {
00216                         case 0x80:
00217                                 outd = &opngen.outdl;
00218                                 break;
00219 
00220                         case 0x40:
00221                                 outd = &opngen.outdr;
00222                                 break;
00223                 }
00224         }
00225         switch(ch->algorithm) {
00226                 case 0:
00227                         ch->connect1 = &opngen.feedback2;
00228                         ch->connect2 = &opngen.feedback3;
00229                         ch->connect3 = &opngen.feedback4;
00230                         outslot = 0x08;
00231                         break;
00232 
00233                 case 1:
00234                         ch->connect1 = &opngen.feedback3;
00235                         ch->connect2 = &opngen.feedback3;
00236                         ch->connect3 = &opngen.feedback4;
00237                         outslot = 0x08;
00238                         break;
00239 
00240                 case 2:
00241                         ch->connect1 = &opngen.feedback4;
00242                         ch->connect2 = &opngen.feedback3;
00243                         ch->connect3 = &opngen.feedback4;
00244                         outslot = 0x08;
00245                         break;
00246 
00247                 case 3:
00248                         ch->connect1 = &opngen.feedback2;
00249                         ch->connect2 = &opngen.feedback4;
00250                         ch->connect3 = &opngen.feedback4;
00251                         outslot = 0x08;
00252                         break;
00253 
00254                 case 4:
00255                         ch->connect1 = &opngen.feedback2;
00256                         ch->connect2 = outd;
00257                         ch->connect3 = &opngen.feedback4;
00258                         outslot = 0x0a;
00259                         break;
00260 
00261                 case 5:
00262                         ch->connect1 = 0;
00263                         ch->connect2 = outd;
00264                         ch->connect3 = outd;
00265                         outslot = 0x0e;
00266                         break;
00267 
00268                 case 6:
00269                         ch->connect1 = &opngen.feedback2;
00270                         ch->connect2 = outd;
00271                         ch->connect3 = outd;
00272                         outslot = 0x0e;
00273                         break;
00274 
00275                 case 7:
00276                 default:
00277                         ch->connect1 = outd;
00278                         ch->connect2 = outd;
00279                         ch->connect3 = outd;
00280                         outslot = 0x0f;
00281         }
00282         ch->connect4 = outd;
00283         ch->outslot = outslot;
00284 }
00285 
00286 static void set_dt1_mul(OPNSLOT *slot, REG8 value) {
00287 
00288         slot->multiple = (SINT32)multipletable[value & 0x0f];
00289         slot->detune1 = detunetable[(value >> 4) & 7];
00290 }
00291 
00292 static void set_tl(OPNSLOT *slot, REG8 value) {
00293 
00294 #if (EVC_BITS >= 7)
00295         slot->totallevel = ((~value) & 0x007f) << (EVC_BITS - 7);
00296 #else
00297         slot->totallevel = ((~value) & 0x007f) >> (7 - EVC_BITS);
00298 #endif
00299 }
00300 
00301 static void set_ks_ar(OPNSLOT *slot, REG8 value) {
00302 
00303         slot->keyscale = ((~value) >> 6) & 3;
00304         value &= 0x1f;
00305         slot->attack = (value)?(attacktable + (value << 1)):nulltable;
00306         slot->env_inc_attack = slot->attack[slot->envratio];
00307         if (slot->env_mode == EM_ATTACK) {
00308                 slot->env_inc = slot->env_inc_attack;
00309         }
00310 }
00311 
00312 static void set_d1r(OPNSLOT *slot, REG8 value) {
00313 
00314         value &= 0x1f;
00315         slot->decay1 = (value)?(decaytable + (value << 1)):nulltable;
00316         slot->env_inc_decay1 = slot->decay1[slot->envratio];
00317         if (slot->env_mode == EM_DECAY1) {
00318                 slot->env_inc = slot->env_inc_decay1;
00319         }
00320 }
00321 
00322 static void set_dt2_d2r(OPNSLOT *slot, REG8 value) {
00323 
00324         value &= 0x1f;
00325         slot->decay2 = (value)?(decaytable + (value << 1)):nulltable;
00326         if (slot->ssgeg1) {
00327                 slot->env_inc_decay2 = 0;
00328         }
00329         else {
00330                 slot->env_inc_decay2 = slot->decay2[slot->envratio];
00331         }
00332         if (slot->env_mode == EM_DECAY2) {
00333                 slot->env_inc = slot->env_inc_decay2;
00334         }
00335 }
00336 
00337 static void set_d1l_rr(OPNSLOT *slot, REG8 value) {
00338 
00339         slot->decaylevel = decayleveltable[(value >> 4)];
00340         slot->release = decaytable + ((value & 0x0f) << 2) + 2;
00341         slot->env_inc_release = slot->release[slot->envratio];
00342         if (slot->env_mode == EM_RELEASE) {
00343                 slot->env_inc = slot->env_inc_release;
00344                 if (value == 0xff) {
00345                         slot->env_mode = EM_OFF;
00346                         slot->env_cnt = EC_OFF;
00347                         slot->env_end = EC_OFF + 1;
00348                         slot->env_inc = 0;
00349                 }
00350         }
00351 }
00352 
00353 static void set_ssgeg(OPNSLOT *slot, REG8 value) {
00354 
00355         value &= 0xf;
00356         if ((value == 0xb) || (value == 0xd)) {
00357                 slot->ssgeg1 = 1;
00358                 slot->env_inc_decay2 = 0;
00359         }
00360         else {
00361                 slot->ssgeg1 = 0;
00362                 slot->env_inc_decay2 = slot->decay2[slot->envratio];
00363         }
00364         if (slot->env_mode == EM_DECAY2) {
00365                 slot->env_inc = slot->env_inc_decay2;
00366         }
00367 }
00368 
00369 static void channleupdate(OPNCH *ch) {
00370 
00371         int             i;
00372         UINT32  fc = ch->keynote[0];                                            // ver0.27
00373         UINT8   kc = ch->kcode[0];
00374         UINT    evr;
00375         OPNSLOT *slot;
00376         int             s;
00377 
00378         slot = ch->slot;
00379         if (!(ch->extop)) {
00380                 for (i=0; i<4; i++, slot++) {
00381                         slot->freq_inc = (fc + slot->detune1[kc]) * slot->multiple;
00382                         evr = kc >> slot->keyscale;
00383                         if (slot->envratio != evr) {
00384                                 slot->envratio = evr;
00385                                 slot->env_inc_attack = slot->attack[evr];
00386                                 slot->env_inc_decay1 = slot->decay1[evr];
00387                                 slot->env_inc_decay2 = slot->decay2[evr];
00388                                 slot->env_inc_release = slot->release[evr];
00389                         }
00390                 }
00391         }
00392         else {
00393                 for (i=0; i<4; i++, slot++) {
00394                         s = extendslot[i];
00395                         slot->freq_inc = (ch->keynote[s] + slot->detune1[ch->kcode[s]])
00396                                                                                                                 * slot->multiple;
00397                         evr = ch->kcode[s] >> slot->keyscale;
00398                         if (slot->envratio != evr) {
00399                                 slot->envratio = evr;
00400                                 slot->env_inc_attack = slot->attack[evr];
00401                                 slot->env_inc_decay1 = slot->decay1[evr];
00402                                 slot->env_inc_decay2 = slot->decay2[evr];
00403                                 slot->env_inc_release = slot->release[evr];
00404                         }
00405                 }
00406         }
00407 }
00408 
00409 
00410 // ----
00411 
00412 void opngen_reset(void) {
00413 
00414         OPNCH   *ch;
00415         UINT    i;
00416         OPNSLOT *slot;
00417         UINT    j;
00418 
00419         ZeroMemory(&opngen, sizeof(opngen));
00420         ZeroMemory(opnch, sizeof(opnch));
00421         opngen.playchannels = 3;
00422 
00423         ch = opnch;
00424         for (i=0; i<OPNCH_MAX; i++) {
00425                 ch->keynote[0] = 0;
00426                 slot = ch->slot;
00427                 for (j=0; j<4; j++) {
00428                         slot->env_mode = EM_OFF;
00429                         slot->env_cnt = EC_OFF;
00430                         slot->env_end = EC_OFF + 1;
00431                         slot->env_inc = 0;
00432                         slot->detune1 = detunetable[0];
00433                         slot->attack = nulltable;
00434                         slot->decay1 = nulltable;
00435                         slot->decay2 = nulltable;
00436                         slot->release = decaytable;
00437                         slot++;
00438                 }
00439                 ch++;
00440         }
00441         for (i=0x30; i<0xc0; i++) {
00442                 opngen_setreg(0, i, 0xff);
00443                 opngen_setreg(3, i, 0xff);
00444                 opngen_setreg(6, i, 0xff);
00445                 opngen_setreg(9, i, 0xff);
00446         }
00447 }
00448 
00449 void opngen_setcfg(REG8 maxch, UINT32 flag) {
00450 
00451         OPNCH   *ch;
00452         UINT    i;
00453 
00454         opngen.playchannels = maxch;
00455         ch = opnch;
00456         if ((flag & OPN_CHMASK) == OPN_STEREO) {
00457                 for (i=0; i<OPNCH_MAX; i++) {
00458                         if (flag & (1 << i)) {
00459                                 ch->stereo = TRUE;
00460                                 set_algorithm(ch);
00461                         }
00462                         ch++;
00463                 }
00464         }
00465         else {
00466                 for (i=0; i<OPNCH_MAX; i++) {
00467                         if (flag & (1 << i)) {
00468                                 ch->stereo = FALSE;
00469                                 set_algorithm(ch);
00470                         }
00471                         ch++;
00472                 }
00473         }
00474 }
00475 
00476 void opngen_setextch(UINT chnum, REG8 data) {
00477 
00478         OPNCH   *ch;
00479 
00480         ch = opnch;
00481         ch[chnum].extop = data;
00482 }
00483 
00484 void opngen_setreg(REG8 chbase, UINT reg, REG8 value) {
00485 
00486         UINT    chpos;
00487         OPNCH   *ch;
00488         OPNSLOT *slot;
00489         UINT    fn;
00490         UINT8   blk;
00491 
00492         chpos = reg & 3;
00493         if (chpos == 3) {
00494                 return;
00495         }
00496         sound_sync();
00497         ch = opnch + chbase + chpos;
00498         if (reg < 0xa0) {
00499                 slot = ch->slot + fmslot[(reg >> 2) & 3];
00500                 switch(reg & 0xf0) {
00501                         case 0x30:                                      // DT1 MUL
00502                                 set_dt1_mul(slot, value);
00503                                 channleupdate(ch);
00504                                 break;
00505 
00506                         case 0x40:                                      // TL
00507                                 set_tl(slot, value);
00508                                 break;
00509 
00510                         case 0x50:                                      // KS AR
00511                                 set_ks_ar(slot, value);
00512                                 channleupdate(ch);
00513                                 break;
00514 
00515                         case 0x60:                                      // D1R
00516                                 set_d1r(slot, value);
00517                                 break;
00518 
00519                         case 0x70:                                      // DT2 D2R
00520                                 set_dt2_d2r(slot, value);
00521                                 channleupdate(ch);
00522                                 break;
00523 
00524                         case 0x80:                                      // D1L RR
00525                                 set_d1l_rr(slot, value);
00526                                 break;
00527 
00528                         case 0x90:
00529                                 set_ssgeg(slot, value);
00530                                 channleupdate(ch);
00531                                 break;
00532                 }
00533         }
00534         else {
00535                 switch(reg & 0xfc) {
00536                         case 0xa0:
00537                                 blk = ch->keyfunc[0] >> 3;
00538                                 fn = ((ch->keyfunc[0] & 7) << 8) + value;
00539                                 ch->kcode[0] = (blk << 2) | kftable[fn >> 7];
00540 //                              ch->keynote[0] = fn * opmbaserate / (1L << (22-blk));
00541                                 ch->keynote[0] = (fn << (opncfg.ratebit + blk)) >> 6;
00542                                 channleupdate(ch);
00543                                 break;
00544 
00545                         case 0xa4:
00546                                 ch->keyfunc[0] = value & 0x3f;
00547                                 break;
00548 
00549                         case 0xa8:
00550                                 ch = opnch + chbase + 2;
00551                                 blk = ch->keyfunc[chpos+1] >> 3;
00552                                 fn = ((ch->keyfunc[chpos+1] & 7) << 8) + value;
00553                                 ch->kcode[chpos+1] = (blk << 2) | kftable[fn >> 7];
00554 //                              ch->keynote[chpos+1] = fn * opmbaserate / (1L << (22-blk));
00555                                 ch->keynote[chpos+1] = (fn << (opncfg.ratebit + blk)) >> 6;
00556                                 channleupdate(ch);
00557                                 break;
00558 
00559                         case 0xac:
00560                                 ch = opnch + chbase + 2;
00561                                 ch->keyfunc[chpos+1] = value & 0x3f;
00562                                 break;
00563 
00564                         case 0xb0:
00565                                 ch->algorithm = (UINT8)(value & 7);
00566                                 value = (value >> 3) & 7;
00567                                 if (value) {
00568                                         ch->feedback = 8 - value;
00569                                 }
00570                                 else {
00571                                         ch->feedback = 0;
00572                                 }
00573                                 set_algorithm(ch);
00574                                 break;
00575 
00576                         case 0xb4:
00577                                 ch->pan = (UINT8)(value & 0xc0);
00578                                 set_algorithm(ch);
00579                                 break;
00580                 }
00581         }
00582 }
00583 
00584 void opngen_keyon(UINT chnum, REG8 value) {
00585 
00586         OPNCH   *ch;
00587         OPNSLOT *slot;
00588         REG8    bit;
00589         UINT    i;
00590 
00591         sound_sync();
00592         opngen.keyreg[chnum] = value;
00593         opngen.playing++;
00594         ch = opnch + chnum;
00595         ch->playing |= value >> 4;
00596         slot = ch->slot;
00597         bit = 0x10;
00598         for (i=0; i<4; i++) {
00599                 if (value & bit) {                                                      // keyon
00600                         if (slot->env_mode <= EM_RELEASE) {
00601                                 slot->freq_cnt = 0;
00602                                 if (i == OPNSLOT1) {
00603                                         ch->op1fb = 0;
00604                                 }
00605                                 slot->env_mode = EM_ATTACK;
00606                                 slot->env_inc = slot->env_inc_attack;
00607                                 slot->env_cnt = EC_ATTACK;
00608                                 slot->env_end = EC_DECAY;
00609                         }
00610                 }
00611                 else {                                                                          // keyoff
00612                         if (slot->env_mode > EM_RELEASE) {
00613                                 slot->env_mode = EM_RELEASE;
00614                                 if (!(slot->env_cnt & EC_DECAY)) {
00615                                         slot->env_cnt = (opncfg.envcurve[slot->env_cnt
00616                                                                                 >> ENV_BITS] << ENV_BITS) + EC_DECAY;
00617                                 }
00618                                 slot->env_end = EC_OFF;
00619                                 slot->env_inc = slot->env_inc_release;
00620                         }
00621                 }
00622                 slot++;
00623                 bit <<= 1;
00624         }
00625 //      keydisp_fmkeyon((UINT8)chnum, value);
00626 }
00627