X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=Pico%2Fsound%2Fym2612.c;h=f626260133862921f74c92e164e3a1b2a613d2f4;hb=8ab3e3c1cf696cb776b14ab511f98aa8ab22797e;hp=56e53127d07017c8811f48f2564bb1c9eef526dd;hpb=cc68a136aa179a5f32fe40208371eb9c2b0aadae;p=picodrive.git diff --git a/Pico/sound/ym2612.c b/Pico/sound/ym2612.c index 56e5312..f626260 100644 --- a/Pico/sound/ym2612.c +++ b/Pico/sound/ym2612.c @@ -1,5 +1,5 @@ /* -** This is a bunch of remains of original fm.c from MAME project. All stuff +** This is a bunch of remains of original fm.c from MAME project. All stuff ** unrelated to ym2612 was removed, multiple chip support was removed, ** some parts of code were slightly rewritten and tied to the emulator. ** @@ -120,11 +120,12 @@ static YM2612 ym2612; #else extern YM2612 *ym2612_940; -extern int *mix_buffer; #define ym2612 (*ym2612_940) #endif +void memset32(int *dest, int c, int count); + #ifndef __GNUC__ #pragma warning (disable:4100) // unreferenced formal parameter @@ -841,7 +842,7 @@ typedef struct UINT32 eg_timer; UINT32 eg_timer_add; UINT32 pack; // 4c: stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16] - UINT32 algo; /* 50 */ + UINT32 algo; /* 50: algo[3], was_update */ INT32 op1_out; } chan_rend_context; @@ -1077,6 +1078,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 } /* update phase counters AFTER output calculations */ @@ -1091,7 +1093,7 @@ void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length) #endif -static void chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flags: stereo, lastchan, disabled, ?, pan_r, pan_l +static int chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flags: stereo, lastchan, disabled, ?, pan_r, pan_l { chan_rend_context ct; @@ -1193,6 +1195,8 @@ static void chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // fla CH->SLOT[SLOT3].phase = ct.phase3; CH->SLOT[SLOT4].phase = ct.phase4; CH->mem_value = ct.mem; + + return (ct.algo & 8) >> 3; // had output } /* update phase increment and envelope generator */ @@ -1584,13 +1588,13 @@ INT32 *ym2612_dacout; /* Generate samples for YM2612 */ -void YM2612UpdateOne_(short *buffer, int length, int stereo) +int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty) { int pan; -#ifndef EXTERNAL_YM2612 - int i; - static int *mix_buffer = 0, mix_buffer_length = 0; -#endif + int active_chs = 0; + + // if !is_buf_empty, it means it has valid samples to mix with, else it may contain trash + if (is_buf_empty) memset32(buffer, 0, length<>2)) << 3; + active_chs |= chan_render(buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)) << 4; + active_chs |= chan_render(buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2) << 5; - /* mix to 32bit temporary buffer */ - chan_render(mix_buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)); // flags: stereo, lastchan, disabled, ?, pan_r, pan_l - chan_render(mix_buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2)); - chan_render(mix_buffer, length, &ym2612.CH[2], stereo|((pan&0x030) )); - chan_render(mix_buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2)); - chan_render(mix_buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)); - chan_render(mix_buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2); - -#ifndef EXTERNAL_YM2612 - /* limit and mix to output buffer */ - if (stereo) { - int *mb = mix_buffer; - for (i = length; i > 0; i--) { - int l, r; - l = r = *buffer; - l += *mb++, r += *mb++; - Limit( l, MAXOUT, MINOUT ); - Limit( r, MAXOUT, MINOUT ); - *buffer++ = l; *buffer++ = r; - } - } else { - for (i = 0; i < length; i++) { - int l = mix_buffer[i]; - l += buffer[i]; - Limit( l, MAXOUT, MINOUT ); - buffer[i] = l; - } - } -#endif + return active_chs; // 1 if buffer updated } @@ -1661,8 +1637,7 @@ void YM2612Init_(int clock, int rate) ym2612_dacen = &ym2612.dacen; ym2612_dacout = &ym2612.dacout; - /* clear everything but the regs */ - memset(ym2612.CH, 0, sizeof(ym2612)-sizeof(ym2612.REGS)-4); + memset(&ym2612, 0, sizeof(ym2612)); init_tables(); ym2612.OPN.ST.clock = clock; @@ -1678,8 +1653,11 @@ void YM2612ResetChip_(void) { int i; + memset(ym2612.REGS, 0, sizeof(ym2612.REGS)); + OPNSetPres( 6*24 ); set_timers( 0x30 ); /* mode 0 , timer reset */ + ym2612.REGS[0x27] = 0x30; ym2612.OPN.eg_timer = 0; ym2612.OPN.eg_cnt = 0; @@ -1690,6 +1668,8 @@ void YM2612ResetChip_(void) { OPNWriteReg(i ,0xc0); OPNWriteReg(i|0x100,0xc0); + ym2612.REGS[i ] = 0xc0; + ym2612.REGS[i|0x100] = 0xc0; } for(i = 0xb2 ; i >= 0x30 ; i-- ) { @@ -1699,6 +1679,7 @@ void YM2612ResetChip_(void) for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(i,0); /* DAC mode clear */ ym2612.dacen = 0; + ym2612.addr_A1 = 0; } @@ -1726,7 +1707,9 @@ int YM2612Write_(unsigned int a, unsigned int v) } addr = ym2612.OPN.ST.address; +#ifndef EXTERNAL_YM2612 ym2612.REGS[addr] = v; +#endif switch( addr & 0xf0 ) { @@ -1824,7 +1807,9 @@ int YM2612Write_(unsigned int a, unsigned int v) } addr = ym2612.OPN.ST.address | 0x100; +#ifndef EXTERNAL_YM2612 ym2612.REGS[addr] = v; +#endif ret = OPNWriteReg(addr, v); break; @@ -1872,7 +1857,7 @@ int YM2612PicoTick_(int n) void YM2612PicoStateLoad_(void) { #ifndef EXTERNAL_YM2612 - int i, old_A1 = ym2612.addr_A1; + int i, real_A1 = ym2612.addr_A1; reset_channels( &ym2612.CH[0], 6 ); @@ -1881,19 +1866,23 @@ void YM2612PicoStateLoad_(void) YM2612Write_(0, i); YM2612Write_(1, ym2612.REGS[i]); } + for(i = 0; i < 0x100; i++) { YM2612Write_(2, i); YM2612Write_(3, ym2612.REGS[i|0x100]); } - ym2612.addr_A1 = old_A1; + ym2612.addr_A1 = real_A1; #else reset_channels( &ym2612.CH[0], 6 ); #endif } +#ifndef EXTERNAL_YM2612 void *YM2612GetRegs(void) { return ym2612.REGS; } +#endif +