SLOT->key = 1;\r
SLOT->phase = 0; /* restart Phase Generator */\r
SLOT->state = EG_ATT; /* phase -> Attack */\r
- SLOT->volume = MAX_ATT_INDEX; /* fix Ecco 2 splash sound */\r
ym2612.slot_mask |= (1<<s) << (c*4);\r
}\r
}\r
return lfo_ampm;\r
}\r
\r
-#define EG_INC_VAL() \\r
- ((1 << ((pack >> ((eg_cnt>>shift)&7)*3)&7)) >> 1)\r
-\r
-INLINE UINT32 update_eg_phase(FM_SLOT *SLOT, UINT32 eg_cnt)\r
+INLINE void update_eg_phase(UINT16 *vol_out, FM_SLOT *SLOT, UINT32 eg_cnt)\r
{\r
INT32 volume = SLOT->volume;\r
+ UINT32 pack = SLOT->eg_pack[SLOT->state - 1];\r
+ UINT32 shift = pack >> 24;\r
+ INT32 eg_inc_val;\r
\r
- switch(SLOT->state)\r
- {\r
- case EG_ATT: /* attack phase */\r
- {\r
- UINT32 pack = SLOT->eg_pack_ar;\r
- UINT32 shift = pack>>24;\r
- if ( !(eg_cnt & ((1<<shift)-1) ) )\r
- {\r
- volume += ( ~volume * EG_INC_VAL() ) >>4;\r
+ if (eg_cnt & ((1 << shift) - 1))\r
+ return;\r
\r
- if (volume <= MIN_ATT_INDEX)\r
- {\r
- volume = MIN_ATT_INDEX;\r
- SLOT->state = EG_DEC;\r
- }\r
- }\r
- break;\r
- }\r
+ eg_inc_val = pack >> ((eg_cnt >> shift) & 7) * 3;\r
+ eg_inc_val = (1 << (eg_inc_val & 7)) >> 1;\r
\r
- case EG_DEC: /* decay phase */\r
+ switch (SLOT->state)\r
+ {\r
+ case EG_ATT: /* attack phase */\r
+ volume += ( ~volume * eg_inc_val ) >> 4;\r
+ if ( volume <= MIN_ATT_INDEX )\r
{\r
- UINT32 pack = SLOT->eg_pack_d1r;\r
- UINT32 shift = pack>>24;\r
- if ( !(eg_cnt & ((1<<shift)-1) ) )\r
- {\r
- volume += EG_INC_VAL();\r
-\r
- if ( volume >= (INT32) SLOT->sl )\r
- SLOT->state = EG_SUS;\r
- }\r
- break;\r
+ volume = MIN_ATT_INDEX;\r
+ SLOT->state = EG_DEC;\r
}\r
+ break;\r
\r
- case EG_SUS: /* sustain phase */\r
- {\r
- UINT32 pack = SLOT->eg_pack_d2r;\r
- UINT32 shift = pack>>24;\r
- if ( !(eg_cnt & ((1<<shift)-1) ) )\r
- {\r
- volume += EG_INC_VAL();\r
+ case EG_DEC: /* decay phase */\r
+ volume += eg_inc_val;\r
+ if ( volume >= (INT32) SLOT->sl )\r
+ SLOT->state = EG_SUS;\r
+ break;\r
\r
- if ( volume >= MAX_ATT_INDEX )\r
- {\r
- volume = MAX_ATT_INDEX;\r
- /* do not change SLOT->state (verified on real chip) */\r
- }\r
- }\r
- break;\r
+ case EG_SUS: /* sustain phase */\r
+ volume += eg_inc_val;\r
+ if ( volume >= MAX_ATT_INDEX )\r
+ {\r
+ volume = MAX_ATT_INDEX;\r
+ /* do not change SLOT->state (verified on real chip) */\r
}\r
+ break;\r
\r
- case EG_REL: /* release phase */\r
+ case EG_REL: /* release phase */\r
+ volume += eg_inc_val;\r
+ if ( volume >= MAX_ATT_INDEX )\r
{\r
- UINT32 pack = SLOT->eg_pack_rr;\r
- UINT32 shift = pack>>24;\r
- if ( !(eg_cnt & ((1<<shift)-1) ) )\r
- {\r
- volume += EG_INC_VAL();\r
-\r
- if ( volume >= MAX_ATT_INDEX )\r
- {\r
- volume = MAX_ATT_INDEX;\r
- SLOT->state = EG_OFF;\r
- }\r
- }\r
- break;\r
+ volume = MAX_ATT_INDEX;\r
+ SLOT->state = EG_OFF;\r
}\r
+ break;\r
}\r
\r
SLOT->volume = volume;\r
- return SLOT->tl + ((UINT32)volume); /* tl is 7bit<<3, volume 0-1023 (0-2039 total) */\r
+ *vol_out = SLOT->tl + volume; /* tl is 7bit<<3, volume 0-1023 (0-2039 total) */\r
}\r
#endif\r
\r
ct->eg_timer -= EG_TIMER_OVERFLOW;\r
ct->eg_cnt++;\r
\r
- if (ct->CH->SLOT[SLOT1].state != EG_OFF) ct->vol_out1 = update_eg_phase(&ct->CH->SLOT[SLOT1], ct->eg_cnt);\r
- if (ct->CH->SLOT[SLOT2].state != EG_OFF) ct->vol_out2 = update_eg_phase(&ct->CH->SLOT[SLOT2], ct->eg_cnt);\r
- if (ct->CH->SLOT[SLOT3].state != EG_OFF) ct->vol_out3 = update_eg_phase(&ct->CH->SLOT[SLOT3], ct->eg_cnt);\r
- if (ct->CH->SLOT[SLOT4].state != EG_OFF) ct->vol_out4 = update_eg_phase(&ct->CH->SLOT[SLOT4], ct->eg_cnt);\r
+ if (ct->CH->SLOT[SLOT1].state != EG_OFF) update_eg_phase(&ct->vol_out1, &ct->CH->SLOT[SLOT1], ct->eg_cnt);\r
+ if (ct->CH->SLOT[SLOT2].state != EG_OFF) update_eg_phase(&ct->vol_out2, &ct->CH->SLOT[SLOT2], ct->eg_cnt);\r
+ if (ct->CH->SLOT[SLOT3].state != EG_OFF) update_eg_phase(&ct->vol_out3, &ct->CH->SLOT[SLOT3], ct->eg_cnt);\r
+ if (ct->CH->SLOT[SLOT4].state != EG_OFF) update_eg_phase(&ct->vol_out4, &ct->CH->SLOT[SLOT4], ct->eg_cnt);\r
}\r
\r
if (ct->pack & 4) continue; /* output disabled */\r
} else {\r
buffer[scounter] += smp;\r
}\r
- ct->algo = 8; // algo is only used in asm, here only bit3 is used\r
+ ct->algo |= 8;\r
}\r
\r
/* update phase counters AFTER output calculations */\r
for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(i,0);\r
/* DAC mode clear */\r
ym2612.dacen = 0;\r
+ ym2612.dacout = 0;\r
ym2612.addr_A1 = 0;\r
}\r
\r
\r
v &= 0xff; /* adjust to 8 bit bus */\r
\r
- switch( a&3){\r
+ switch( a & 3 ){\r
case 0: /* address port 0 */\r
+ case 2: /* address port 1 */\r
ym2612.OPN.ST.address = v;\r
- ym2612.addr_A1 = 0;\r
- ret=0;\r
+ ym2612.addr_A1 = (a & 2) >> 1;\r
+ ret = 0;\r
break;\r
\r
- case 1: /* data port 0 */\r
- if (ym2612.addr_A1 != 0) {\r
- ret=0;\r
- break; /* verified on real YM2608 */\r
- }\r
-\r
- addr = ym2612.OPN.ST.address;\r
+ case 1:\r
+ case 3: /* data port */\r
+ addr = ym2612.OPN.ST.address | ((int)ym2612.addr_A1 << 8);\r
\r
- switch( addr & 0xf0 )\r
+ switch( addr & 0x1f0 )\r
{\r
case 0x20: /* 0x20-0x2f Mode */\r
switch( addr )\r
else\r
{\r
ym2612.OPN.lfo_inc = 0;\r
+ ym2612.OPN.lfo_cnt = 0;\r
}\r
break;\r
#if 0 // handled elsewhere\r
ret = OPNWriteReg(addr,v);\r
}\r
break;\r
-\r
- case 2: /* address port 1 */\r
- ym2612.OPN.ST.address = v;\r
- ym2612.addr_A1 = 1;\r
- ret=0;\r
- break;\r
-\r
- case 3: /* data port 1 */\r
- if (ym2612.addr_A1 != 1) {\r
- ret=0;\r
- break; /* verified on real YM2608 */\r
- }\r
-\r
- addr = ym2612.OPN.ST.address | 0x100;\r
-\r
- ret = OPNWriteReg(addr, v);\r
- break;\r
}\r
\r
return ret;\r