@@ -101,6 +101,7 @@ struct _bsmt2000_state
101101 UINT8 adpcm ; // ADPCM/compressed enabled?
102102 UINT8 mode ; // current mode (0,1,5,6,7)
103103 UINT8 last_register ; // last register written
104+ UINT16 latch ; // buffer to combine 8-bit writes to a 16-bit words
104105 UINT32 clock ; // Chip clock
105106
106107 // ADPCM/compressed state
@@ -271,9 +272,7 @@ static void device_stop_bsmt2000(void *info)
271272/* ==== Device Reset ==== */
272273static void device_reset_bsmt2000 (void * info ) {
273274 bsmt2000_state * chip = (bsmt2000_state * )info ;
274- UINT32 muteMask ;
275275
276- muteMask = bsmt2000_get_mute_mask (chip );
277276 init_all_voices (chip );
278277 chip -> adpcm_current = 0 ;
279278 chip -> adpcm_delta_n = 10 ;
@@ -313,7 +312,6 @@ static void device_reset_bsmt2000(void *info) {
313312 chip -> adpcm = 0 ;
314313 chip -> mode = 6 ;
315314 break ;
316-
317315 /* mode 7: 32kHz, 9 channel PCM, stereo */
318316 case 7 :
319317 chip -> sample_rate = chip -> clock / 750. ;
@@ -323,29 +321,26 @@ static void device_reset_bsmt2000(void *info) {
323321 chip -> mode = 7 ;
324322 break ;
325323 }
326- bsmt2000_set_mute_mask (chip , muteMask );
327- if (chip -> SmpRateFunc != NULL )
328- chip -> SmpRateFunc (chip -> SmpRateData , chip -> sample_rate );
329-
324+ if (chip -> SmpRateFunc != NULL )
325+ chip -> SmpRateFunc (chip -> SmpRateData , (UINT32 )chip -> sample_rate );
330326}
331327/* ==== Register/Command Interface ==== */
332328
333329static void bsmt2000_w (void * info , UINT8 offset , UINT8 data )
334330{
335331 bsmt2000_state * chip = (bsmt2000_state * )info ;
336- static UINT16 latch = 0 ;
337332 switch (offset )
338333 {
339334 case 0 :
340- latch = (latch & 0x00ff ) | (data << 8 );
335+ chip -> latch = (chip -> latch & 0x00ff ) | (data << 8 );
341336 break ;
342337 case 1 :
343- latch = (latch & 0xff00 ) | data ;
338+ chip -> latch = (chip -> latch & 0xff00 ) | data ;
344339 break ;
345340 case 2 :
346- bsmt2000_write_data (chip , data , latch );
341+ bsmt2000_write_data (chip , data , chip -> latch );
347342 break ;
348- case 3 :
343+ case 0x10 :
349344 chip -> last_register = data ;
350345 device_reset_bsmt2000 (info );
351346 break ;
@@ -448,8 +443,7 @@ static void bsmt2000_write_rom(void *info, UINT32 offset, UINT32 length, const U
448443 if (offset > chip -> sample_rom_length ) return ;
449444 if (offset + length > chip -> sample_rom_length )
450445 length = chip -> sample_rom_length - offset ;
451- for (UINT32 i = 0 ; i < length ; i ++ )
452- chip -> sample_rom [offset + i ] = data [i ];
446+ memcpy (& chip -> sample_rom [offset ], data , length );
453447}
454448
455449/* ==== Mute Mask ==== */
@@ -479,15 +473,16 @@ static void bsmt2000_set_log_cb(void* info, DEVCB_LOG func, void* param)
479473}
480474
481475/* ==== Interpolation Macro ==== */
482- #define INTERPOLATE (s1 ,s2 ,frac ) (((s1) * (0x10000 - ((frac)&0xffff)) + (s2) * ((frac)&0xffff)) >> 16)
476+ #define INTERPOLATE (s1 ,s2 ,frac ) (((s1) * (INT32)( 0x10000 - ((frac)&0xffff)) + (s2) * (INT32) ((frac)&0xffff)) >> 16)
483477
484478/* ==== Sound Update ==== */
485479static void bsmt2000_update (void * param , UINT32 samples , DEV_SMPL * * outputs )
486480{
487481 bsmt2000_state * chip = (bsmt2000_state * )param ;
488- INT64 left [BSMT2000_SAMPLE_CHUNK ], right [BSMT2000_SAMPLE_CHUNK ];
482+ INT32 left [BSMT2000_SAMPLE_CHUNK ];
483+ INT32 right [BSMT2000_SAMPLE_CHUNK ];
489484 bsmt2000_voice * voice ;
490- int samp , v , length = MIN (samples , BSMT2000_SAMPLE_CHUNK );
485+ int samp , v , length = MIN (samples , BSMT2000_SAMPLE_CHUNK ); // TODO: allow updating in larger chunks
491486
492487 if (!chip -> sample_rom || !chip -> sample_rom_length )
493488 {
@@ -501,27 +496,40 @@ static void bsmt2000_update(void *param, UINT32 samples, DEV_SMPL **outputs)
501496 // PCM voices
502497 for (v = 0 ; v < chip -> voices ; v ++ )
503498 {
499+ UINT8 * base ;
500+ UINT32 rate , pos ;
501+ INT32 lvol , rvol ;
502+
504503 if (chip -> Muted [v ])
505504 continue ;
506505 voice = & chip -> voice [v ];
507506 if (voice -> reg [BSMT2000_REG_BANK ] >= chip -> total_banks ) // REG_BANK
508507 continue ;
509- UINT8 * base = chip -> sample_rom + voice -> reg [BSMT2000_REG_BANK ] * BSMT2000_ROM_BANKSIZE ;
510- UINT32 rate = voice -> adjusted_rate ;
511- UINT32 pos = voice -> position ;
512- INT32 rvol = voice -> reg [BSMT2000_REG_RIGHTVOL ]; // REG_RIGHTVOL
513- INT32 lvol = chip -> stereo ? voice -> reg [BSMT2000_REG_LEFTVOL ] : rvol ; // REG_LEFTVOL
508+ base = chip -> sample_rom + voice -> reg [BSMT2000_REG_BANK ] * BSMT2000_ROM_BANKSIZE ;
509+ rate = voice -> adjusted_rate ;
510+ pos = voice -> position ;
511+ rvol = voice -> reg [BSMT2000_REG_RIGHTVOL ]; // REG_RIGHTVOL
512+ lvol = chip -> stereo ? voice -> reg [BSMT2000_REG_LEFTVOL ] : rvol ; // REG_LEFTVOL
514513 if (chip -> stereo && !chip -> right_volume_set )
515514 rvol = lvol ;
516- int remaining = length ;
517515
518- while ( remaining -- ) {
516+ for ( samp = 0 ; samp < length ; samp ++ ) {
519517 INT32 idx = pos >> 16 ;
520- INT32 s1 = ((INT8 )base [idx ] << 8 );
521- INT32 s2 = ((INT8 )base [idx + 1 ] << 8 );
522- INT32 sample = (s1 * (INT32 )(0x10000 - (pos & 0xffff )) + (s2 * (INT32 )(pos & 0xffff ))) >> 16 ;
523- left [length - remaining - 1 ] += sample * lvol ;
524- right [length - remaining - 1 ] += sample * rvol ;
518+ INT32 sample ;
519+ if (1 )
520+ {
521+ // no interpolation (original chip behaviour)
522+ sample = (INT8 )base [idx ] << 8 ;
523+ }
524+ else
525+ {
526+ // linear interpolation (softer samples, breaks SFX in "Tales from the Crypt")
527+ INT32 s1 = (INT8 )base [idx ] << 8 ;
528+ INT32 s2 = (INT8 )base [idx + 1 ] << 8 ;
529+ sample = INTERPOLATE (s1 , s2 , pos );
530+ }
531+ left [samp ] += (sample * lvol ) >> 16 ;
532+ right [samp ] += (sample * rvol ) >> 16 ;
525533 pos += rate ;
526534 if (pos >= voice -> loop_stop_position )
527535 pos += voice -> loop_start_position - voice -> loop_stop_position ;
@@ -542,13 +550,12 @@ static void bsmt2000_update(void *param, UINT32 samples, DEV_SMPL **outputs)
542550 INT32 lvol = chip -> stereo ? voice -> reg [BSMT2000_REG_LEFTVOL ] : rvol ;
543551 if (chip -> stereo && !chip -> right_volume_set )
544552 rvol = lvol ;
545- int remaining = length ;
546553
547- while ( remaining -- && pos < voice -> loop_stop_position )
554+ for ( samp = 0 ; samp < length && pos < voice -> loop_stop_position ; samp ++ )
548555 {
549556 UINT32 oldpos = pos ;
550- left [length - remaining - 1 ] += chip -> adpcm_current * (lvol * 2 );
551- right [length - remaining - 1 ] += chip -> adpcm_current * (rvol * 2 );
557+ left [samp ] += ( chip -> adpcm_current * (lvol * 2 )) >> 16 ;
558+ right [samp ] += ( chip -> adpcm_current * (rvol * 2 )) >> 16 ;
552559
553560 pos += rate ;
554561 if ((oldpos ^ pos ) & 0x8000 )
@@ -583,12 +590,12 @@ static void bsmt2000_update(void *param, UINT32 samples, DEV_SMPL **outputs)
583590
584591 // Output clamp and write
585592 for (samp = 0 ; samp < length ; samp ++ ) {
586- INT64 l = left [samp ] >> 16 ;
587- INT64 r = right [samp ] >> 16 ;
593+ INT32 l = left [samp ];
594+ INT32 r = right [samp ];
588595 l = (l > 32767 ) ? 32767 : (l < -32768 ) ? -32768 : l ;
589596 r = (r > 32767 ) ? 32767 : (r < -32768 ) ? -32768 : r ;
590- outputs [0 ][samp ] = l ;
591- outputs [1 ][samp ] = r ;
597+ outputs [0 ][samp ] = ( DEV_SMPL ) l ;
598+ outputs [1 ][samp ] = ( DEV_SMPL ) r ;
592599 }
593600}
594601
0 commit comments