@@ -660,9 +660,9 @@ struct Ns {
660660}
661661
662662impl Ns {
663- fn new ( sr : u32 ) -> Self {
663+ fn power_up ( ) -> Self {
664664 Self {
665- buf : Blip :: power_up ( sr ) ,
665+ buf : Blip :: power_up ( SAMPLE_RATE ) ,
666666 reg : Reg :: power_up ( ) ,
667667 tmr : Tmr :: power_up ( 8 ) ,
668668 lc : Lc :: power_up ( ) ,
@@ -751,61 +751,53 @@ const RD: [u8; 0x30] = [
751751
752752pub struct Apu {
753753 glo : Rc < RefCell < Global > > ,
754- pub buffer : Arc < Mutex < Vec < ( f32 , f32 ) > > > ,
755- sr : u32 ,
756754
757- // NR50/51/52
758- nr50 : u8 ,
759- nr51 : u8 ,
760- pwr : bool ,
755+ pub data : Arc < Mutex < Vec < ( f32 , f32 ) > > > ,
756+ pub sdiv : u16 ,
761757
762758 ch1 : Sq1 ,
763759 ch2 : Sq2 ,
764760 ch3 : Wv ,
765761 ch4 : Ns ,
766-
767- // Frame sequencer + 512 Hz divider.
762+ fc : u32 ,
768763 fs : Fseq ,
764+ fs_skip : bool ,
769765 ft : Tmr ,
770- skip_fs : bool ,
771-
772- // sdiv at the moment of the current APU bus write; the MMU writes this
773- // before every `sb` so the NR52 power-on handler can phase-align FS.
774- pub sdiv_cache : u16 ,
775-
776- // Monotonic frame counter (one per FS-divider fire); used together with
777- // `t_frame`/`t_apu_n` in CH3 to extrapolate live wave-RAM access.
778- fc : u32 ,
766+ nr50 : u8 ,
767+ nr51 : u8 ,
768+ pwr : bool ,
769+ sr : u32 ,
779770}
780771
781772impl Apu {
782773 pub fn power_up ( glo : Rc < RefCell < Global > > , sr : u32 ) -> Self {
783774 Self {
784775 glo,
785- buffer : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
786- sr,
787- nr50 : 0 ,
788- nr51 : 0 ,
789- pwr : false ,
776+ data : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
777+ sdiv : 0 ,
790778 ch1 : Sq1 :: power_up ( ) ,
791779 ch2 : Sq2 :: power_up ( ) ,
792780 ch3 : Wv :: power_up ( ) ,
793- ch4 : Ns :: new ( sr) ,
781+ ch4 : Ns :: power_up ( ) ,
782+ fc : 0 ,
794783 fs : Fseq :: power_up ( ) ,
784+ fs_skip : false ,
795785 ft : Tmr :: power_up ( CLOCK_FREQUENCY / 512 ) ,
796- skip_fs : false ,
797- sdiv_cache : 0 ,
798- fc : 0 ,
786+ nr50 : 0 ,
787+ nr51 : 0 ,
788+ pwr : false ,
789+ sr,
799790 }
800791 }
801792
802- // ─── Mixer & output ────────────────────────────────────────────────────
803-
804- fn vol_l ( & self ) -> f32 {
805- f32:: from ( ( self . nr50 >> 4 ) & 0x07 ) / 7.0 / 15.0 * 0.25
806- }
807- fn vol_r ( & self ) -> f32 {
808- f32:: from ( self . nr50 & 0x07 ) / 7.0 / 15.0 * 0.25
793+ fn add ( & self , l : & [ f32 ] , r : & [ f32 ] ) {
794+ let mut b = self . data . lock ( ) . unwrap ( ) ;
795+ for ( a, c) in l. iter ( ) . zip ( r) {
796+ if b. len ( ) > self . sr as usize {
797+ return ;
798+ }
799+ b. push ( ( * a, * c) ) ;
800+ }
809801 }
810802
811803 fn mix ( & mut self ) {
@@ -846,19 +838,17 @@ impl Apu {
846838 mix_into ( & t[ ..c4] , & mut l, & mut r, pan & 0x80 != 0 , pan & 0x08 != 0 ) ;
847839
848840 debug_assert ! ( c1 == c2 && c2 == c3 && c3 == c4) ;
849- self . push ( & l[ ..c1] , & r[ ..c1] ) ;
841+ self . add ( & l[ ..c1] , & r[ ..c1] ) ;
850842 done += c1;
851843 }
852844 }
853845
854- fn push ( & self , l : & [ f32 ] , r : & [ f32 ] ) {
855- let mut b = self . buffer . lock ( ) . unwrap ( ) ;
856- for ( a, c) in l. iter ( ) . zip ( r) {
857- if b. len ( ) > self . sr as usize {
858- return ;
859- }
860- b. push ( ( * a, * c) ) ;
861- }
846+ fn vol_l ( & self ) -> f32 {
847+ f32:: from ( ( self . nr50 >> 4 ) & 0x07 ) / 7.0 / 15.0 * 0.25
848+ }
849+
850+ fn vol_r ( & self ) -> f32 {
851+ f32:: from ( self . nr50 & 0x07 ) / 7.0 / 15.0 * 0.25
862852 }
863853
864854 // ─── Helpers ───────────────────────────────────────────────────────────
@@ -932,8 +922,8 @@ impl Apu {
932922 // the next falling edge of sdiv bit 12. If that bit is already high at
933923 // power-on, the very first FS event is skipped (hardware glitch).
934924 self . fs . s = 7 ;
935- self . ft . n = u32:: from ( self . sdiv_cache ) % ( CLOCK_FREQUENCY / 512 ) ;
936- self . skip_fs = self . sdiv_cache & 0x1000 != 0 ;
925+ self . ft . n = u32:: from ( self . sdiv ) % ( CLOCK_FREQUENCY / 512 ) ;
926+ self . fs_skip = self . sdiv & 0x1000 != 0 ;
937927 }
938928
939929 fn status ( & self ) -> u8 {
@@ -1030,7 +1020,7 @@ impl Memory for Apu {
10301020 0xff1d => {
10311021 // Record d1 (2-MHz cycles from first trigger to this NR33 write).
10321022 if self . glo . borrow ( ) . term == Term :: DMG && self . ch3 . on && self . ch3 . reg . dac_wv ( ) {
1033- let dt = self . sdiv_cache . wrapping_sub ( self . ch3 . t_s_div ) as u32 ;
1023+ let dt = self . sdiv . wrapping_sub ( self . ch3 . t_s_div ) as u32 ;
10341024 self . ch3 . d1 = dt / 2 ;
10351025 }
10361026 self . ch3 . sb ( a, v) ;
@@ -1059,7 +1049,7 @@ impl Memory for Apu {
10591049impl Apu {
10601050 fn nr34sb ( & mut self , v : u8 , xtra : bool ) {
10611051 let was = self . ch3 . on && self . ch3 . reg . dac_wv ( ) ;
1062- let sdiv = self . sdiv_cache ;
1052+ let sdiv = self . sdiv ;
10631053 let trig = v & 0x80 != 0 ;
10641054
10651055 let dmg_off = if trig && was && self . glo . borrow ( ) . term == Term :: DMG {
@@ -1113,8 +1103,8 @@ impl Ticker for Apu {
11131103
11141104 if !self . pwr {
11151105 for _ in 0 ..n {
1116- if self . skip_fs {
1117- self . skip_fs = false ;
1106+ if self . fs_skip {
1107+ self . fs_skip = false ;
11181108 continue ;
11191109 }
11201110 self . fs . step ( ) ;
@@ -1124,8 +1114,8 @@ impl Ticker for Apu {
11241114 }
11251115
11261116 for _ in 0 ..n {
1127- if self . skip_fs {
1128- self . skip_fs = false ;
1117+ if self . fs_skip {
1118+ self . fs_skip = false ;
11291119 self . fc = self . fc . wrapping_add ( 1 ) ;
11301120 continue ;
11311121 }
0 commit comments