X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=pico%2Fsound%2Fym2612.c;h=e712278ba1bcb3cd73401d19599472b908f252ae;hb=151df6adf9d63c9b8c8a61946243800610ac3a65;hp=efe5054e9e8d3acc46c33485097838cb9092f5ab;hpb=4f3ad415128d7d33bf340059aa4f173ec7b620fe;p=picodrive.git diff --git a/pico/sound/ym2612.c b/pico/sound/ym2612.c index efe5054..e712278 100644 --- a/pico/sound/ym2612.c +++ b/pico/sound/ym2612.c @@ -739,83 +739,57 @@ INLINE int advance_lfo(int lfo_ampm, UINT32 lfo_cnt_old, UINT32 lfo_cnt) return lfo_ampm; } -#define EG_INC_VAL() \ - ((1 << ((pack >> ((eg_cnt>>shift)&7)*3)&7)) >> 1) - -INLINE UINT32 update_eg_phase(FM_SLOT *SLOT, UINT32 eg_cnt) +INLINE void update_eg_phase(UINT16 *vol_out, FM_SLOT *SLOT, UINT32 eg_cnt) { INT32 volume = SLOT->volume; + UINT32 pack = SLOT->eg_pack[SLOT->state - 1]; + UINT32 shift = pack >> 24; + INT32 eg_inc_val; - switch(SLOT->state) - { - case EG_ATT: /* attack phase */ - { - UINT32 pack = SLOT->eg_pack_ar; - UINT32 shift = pack>>24; - if ( !(eg_cnt & ((1<>4; + if (eg_cnt & ((1 << shift) - 1)) + return; - if (volume <= MIN_ATT_INDEX) - { - volume = MIN_ATT_INDEX; - SLOT->state = EG_DEC; - } - } - break; - } + eg_inc_val = pack >> ((eg_cnt >> shift) & 7) * 3; + eg_inc_val = (1 << (eg_inc_val & 7)) >> 1; - case EG_DEC: /* decay phase */ + switch (SLOT->state) + { + case EG_ATT: /* attack phase */ + volume += ( ~volume * eg_inc_val ) >> 4; + if ( volume <= MIN_ATT_INDEX ) { - UINT32 pack = SLOT->eg_pack_d1r; - UINT32 shift = pack>>24; - if ( !(eg_cnt & ((1<= (INT32) SLOT->sl ) - SLOT->state = EG_SUS; - } - break; + volume = MIN_ATT_INDEX; + SLOT->state = EG_DEC; } + break; - case EG_SUS: /* sustain phase */ - { - UINT32 pack = SLOT->eg_pack_d2r; - UINT32 shift = pack>>24; - if ( !(eg_cnt & ((1<= (INT32) SLOT->sl ) + SLOT->state = EG_SUS; + break; - if ( volume >= MAX_ATT_INDEX ) - { - volume = MAX_ATT_INDEX; - /* do not change SLOT->state (verified on real chip) */ - } - } - break; + case EG_SUS: /* sustain phase */ + volume += eg_inc_val; + if ( volume >= MAX_ATT_INDEX ) + { + volume = MAX_ATT_INDEX; + /* do not change SLOT->state (verified on real chip) */ } + break; - case EG_REL: /* release phase */ + case EG_REL: /* release phase */ + volume += eg_inc_val; + if ( volume >= MAX_ATT_INDEX ) { - UINT32 pack = SLOT->eg_pack_rr; - UINT32 shift = pack>>24; - if ( !(eg_cnt & ((1<= MAX_ATT_INDEX ) - { - volume = MAX_ATT_INDEX; - SLOT->state = EG_OFF; - } - } - break; + volume = MAX_ATT_INDEX; + SLOT->state = EG_OFF; } + break; } SLOT->volume = volume; - return SLOT->tl + ((UINT32)volume); /* tl is 7bit<<3, volume 0-1023 (0-2039 total) */ + *vol_out = SLOT->tl + volume; /* tl is 7bit<<3, volume 0-1023 (0-2039 total) */ } #endif @@ -873,10 +847,10 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length) ct->eg_timer -= EG_TIMER_OVERFLOW; ct->eg_cnt++; - if (ct->CH->SLOT[SLOT1].state != EG_OFF) ct->vol_out1 = update_eg_phase(&ct->CH->SLOT[SLOT1], ct->eg_cnt); - if (ct->CH->SLOT[SLOT2].state != EG_OFF) ct->vol_out2 = update_eg_phase(&ct->CH->SLOT[SLOT2], ct->eg_cnt); - if (ct->CH->SLOT[SLOT3].state != EG_OFF) ct->vol_out3 = update_eg_phase(&ct->CH->SLOT[SLOT3], ct->eg_cnt); - if (ct->CH->SLOT[SLOT4].state != EG_OFF) ct->vol_out4 = update_eg_phase(&ct->CH->SLOT[SLOT4], ct->eg_cnt); + if (ct->CH->SLOT[SLOT1].state != EG_OFF) update_eg_phase(&ct->vol_out1, &ct->CH->SLOT[SLOT1], ct->eg_cnt); + if (ct->CH->SLOT[SLOT2].state != EG_OFF) update_eg_phase(&ct->vol_out2, &ct->CH->SLOT[SLOT2], ct->eg_cnt); + if (ct->CH->SLOT[SLOT3].state != EG_OFF) update_eg_phase(&ct->vol_out3, &ct->CH->SLOT[SLOT3], ct->eg_cnt); + if (ct->CH->SLOT[SLOT4].state != EG_OFF) update_eg_phase(&ct->vol_out4, &ct->CH->SLOT[SLOT4], ct->eg_cnt); } if (ct->pack & 4) continue; /* output disabled */ @@ -1071,7 +1045,7 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length) } else { buffer[scounter] += smp; } - ct->algo = 8; // algo is only used in asm, here only bit3 is used + ct->algo |= 8; } /* update phase counters AFTER output calculations */ @@ -1719,22 +1693,19 @@ int YM2612Write_(unsigned int a, unsigned int v) v &= 0xff; /* adjust to 8 bit bus */ - switch( a&3){ + switch( a & 3 ){ case 0: /* address port 0 */ + case 2: /* address port 1 */ ym2612.OPN.ST.address = v; - ym2612.addr_A1 = 0; - ret=0; + ym2612.addr_A1 = (a & 2) >> 1; + ret = 0; break; - case 1: /* data port 0 */ - if (ym2612.addr_A1 != 0) { - ret=0; - break; /* verified on real YM2608 */ - } - - addr = ym2612.OPN.ST.address; + case 1: + case 3: /* data port */ + addr = ym2612.OPN.ST.address | ((int)ym2612.addr_A1 << 8); - switch( addr & 0xf0 ) + switch( addr & 0x1f0 ) { case 0x20: /* 0x20-0x2f Mode */ switch( addr ) @@ -1747,6 +1718,7 @@ int YM2612Write_(unsigned int a, unsigned int v) else { ym2612.OPN.lfo_inc = 0; + ym2612.OPN.lfo_cnt = 0; } break; #if 0 // handled elsewhere @@ -1816,23 +1788,6 @@ int YM2612Write_(unsigned int a, unsigned int v) ret = OPNWriteReg(addr,v); } break; - - case 2: /* address port 1 */ - ym2612.OPN.ST.address = v; - ym2612.addr_A1 = 1; - ret=0; - break; - - case 3: /* data port 1 */ - if (ym2612.addr_A1 != 1) { - ret=0; - break; /* verified on real YM2608 */ - } - - addr = ym2612.OPN.ST.address | 0x100; - - ret = OPNWriteReg(addr, v); - break; } return ret;