diff --git a/build.rs b/build.rs
index 42f31d8..13d9b4c 100644
--- a/build.rs
+++ b/build.rs
@@ -6,7 +6,7 @@ fn main() {
     let mut consts = ConstWriter::for_build("lsdpack_bc")
         .unwrap()
         .finish_dependencies();
-    let bytes: Vec<u8> = SONG_SOURCE
+    let mut bytes: Vec<u8> = SONG_SOURCE
         .lines()
         .map(|s| s.trim().strip_prefix("DB "))
         .flatten() // filter to lines starting with DB
@@ -29,6 +29,12 @@ fn main() {
         .flatten() // filter to lines from SongLocations
         .map(|s| usize::from_str_radix(s.split_once('$').unwrap().1, 16).unwrap() - 0x4000)
         .collect();
+    // gba psg has inverted wave channel polarity
+    for sample_pair in &mut bytes[0..*song_positions.iter().min().unwrap()] {
+        let upper = *sample_pair & 0xF0;
+        let lower = *sample_pair & 0x0F;
+        *sample_pair = (0xF0 - upper) | (0x0F - lower);
+    }
     consts.add_array("LSDPACK_DATA", "u8", &bytes);
     consts.add_array("LSDPACK_SONG_POSITIONS", "usize", &song_positions);
 }
diff --git a/src/lsdpack.rs b/src/lsdpack.rs
index d0b0aba..f486609 100644
--- a/src/lsdpack.rs
+++ b/src/lsdpack.rs
@@ -1,9 +1,10 @@
+use core::{fmt::Write, ops::Add};
 use gba::prelude::*;
 use voladdress::{Safe, VolAddress};
 
 #[allow(dead_code)]
 #[repr(u8)]
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 enum LsdpackCmd {
     // special commands (not just plain register writes)
     EndTick = 0,
@@ -139,11 +140,24 @@ impl Lsdpack {
     fn write_next_samples(&mut self) {
         let ptr = self.sample_ptr;
         self.sample_ptr += 16;
-        //let sound_enabled = SOUND_ENABLED.read();
-        //SOUND_ENABLED.write(sound_enabled.with_wave_playing(false));
-        let lrvol = LEFT_RIGHT_VOLUME.read();
-        LEFT_RIGHT_VOLUME.write(lrvol.with_wave_left(false).with_wave_right(false));
-        WAVE_BANK.write(WaveBank::new().with_enabled(false));
+
+        // let sound_enabled = SOUND_ENABLED.read();
+        // SOUND_ENABLED.write(sound_enabled.with_wave_playing(false));
+
+        //let lrvol = LEFT_RIGHT_VOLUME.read();
+        //LEFT_RIGHT_VOLUME.write(lrvol.with_wave_left(false).with_wave_right(false));
+
+        let wb = WAVE_BANK.read();
+        //WAVE_BANK.write(WaveBank::new().with_enabled(false));
+
+        let wave_ram_ptr = (WAVE_RAM.as_mut_ptr() as *mut u8);
+        for i in 0..16 {
+            unsafe {
+                wave_ram_ptr.add(i).write_volatile(self.data[ptr + i]);
+            }
+        }
+
+        /*
         WAVE_RAM.index(0).write(u32::from_le_bytes(
             TryFrom::try_from(&self.data[ptr..ptr + 4]).unwrap(),
         ));
@@ -156,10 +170,20 @@ impl Lsdpack {
         WAVE_RAM.index(3).write(u32::from_le_bytes(
             TryFrom::try_from(&self.data[ptr + 12..ptr + 16]).unwrap(),
         ));
-        WAVE_BANK.write(WaveBank::new().with_enabled(true));
-        //SOUND_ENABLED.write(sound_enabled);
-        LEFT_RIGHT_VOLUME.write(lrvol);
-        WAVE_FREQ.write(WaveFrequency::new().with_length(self.sample_pitch));
+        */
+
+        //WAVE_BANK.write(WaveBank::new().with_enabled(true));
+        WAVE_BANK.write(
+            WaveBank::new()
+                .with_enabled(true)
+                .with_two_banks(false)
+                .with_bank1(!wb.bank1()),
+        );
+
+        // SOUND_ENABLED.write(sound_enabled);
+        //LEFT_RIGHT_VOLUME.write(lrvol);
+
+        unsafe { WAVE_FREQ.cast() }.write(self.sample_pitch);
     }
 
     #[link_section = ".iwram"]
@@ -183,6 +207,33 @@ impl Lsdpack {
             ongoing = flagged_ongoing;
             ongoing &= self.apply_cmd(cmd);
         }
+
+        /* // stupid hack while testing. only enable wav channel so i can hear it at all
+        SOUND_ENABLED.write(
+            SoundEnable::new()
+                .with_tone1_playing(false)
+                .with_tone2_playing(false)
+                .with_wave_playing(true)
+                .with_noise_playing(false)
+                .with_enabled(true),
+        );
+        LEFT_RIGHT_VOLUME.write(
+            LeftRightVolume::new()
+                .with_tone1_left(false)
+                .with_tone1_right(false)
+                .with_tone2_left(false)
+                .with_tone2_right(false)
+                .with_wave_left(true)
+                .with_wave_right(true)
+                .with_noise_right(false)
+                .with_noise_left(false)
+                .with_left_volume(3)
+                .with_right_volume(3),
+        );
+        // */
+
+        //WAVE_BANK.write(WaveBank::new().with_enabled(true));
+        //WAVE_LEN_VOLUME.write(WaveLenVolume::new().with_length(255).with_volume(1));
     }
 
     #[link_section = ".iwram"]
@@ -206,13 +257,21 @@ impl Lsdpack {
     #[link_section = ".iwram"]
     fn write_lsb<T>(&mut self, voladdr: VolAddress<T, Safe, Safe>) {
         let voladdr = unsafe { voladdr.cast::<u16>() };
-        voladdr.write((voladdr.read() & 0xFF00) | (self.next_byte() as u16));
+        //voladdr.write((voladdr.read() & 0xFF00) | (self.next_byte() as u16));
+        unsafe {
+            (voladdr.as_mut_ptr() as *mut u8).write_volatile(self.next_byte());
+        }
     }
 
     #[link_section = ".iwram"]
     fn write_msb<T>(&mut self, voladdr: VolAddress<T, Safe, Safe>) {
         let voladdr = unsafe { voladdr.cast::<u16>() };
-        voladdr.write((voladdr.read() & 0xFF) | ((self.next_byte() as u16) << 8));
+        //voladdr.write((voladdr.read() & 0xFF) | ((self.next_byte() as u16) << 8));
+        unsafe {
+            (voladdr.as_mut_ptr() as *mut u8)
+                .add(1)
+                .write_volatile(self.next_byte());
+        }
     }
 
     #[link_section = ".iwram"]
@@ -225,6 +284,22 @@ impl Lsdpack {
     #[link_section = ".iwram"]
     fn apply_cmd(&mut self, cmd: LsdpackCmd) -> bool {
         use LsdpackCmd::*;
+        /*
+        if let Ok(mut logger) =
+            gba::mgba::MgbaBufferedLogger::try_new(gba::mgba::MgbaMessageLevel::Info)
+        {
+            match cmd {
+                SampleStart | SampleNext | WavOnOff | WavLength | WavEnv | WavPitchLsb
+                | WavPitchMsb | ChannelVolume | Pan | SoundOffOn | WavePattern0 | WavePattern1
+                | WavePattern2 | WavePattern3 | WavePattern4 | WavePattern5 | WavePattern6
+                | WavePattern7 | WavePattern8 | WavePattern9 | WavePatternA | WavePatternB
+                | WavePatternC | WavePatternD | WavePatternE | WavePatternF => {
+                    writeln!(logger, "{:?}", cmd).ok();
+                }
+                _ => {}
+            }
+        }
+        // */
         match cmd {
             // special commands:
             EndTick => return false,
@@ -242,7 +317,6 @@ impl Lsdpack {
             NextBank => { /* lol */ }
             AmpDecPu0 => {
                 // https://github.com/LIJI32/SameBoy/blob/27b5935b8d0e0af988bcac8e55e92703af24f335/Core/apu.c#L341
-                /*
                 let base = TONE1_PATTERN.read();
                 TONE1_PATTERN.write(
                     base.with_volume(0)
@@ -259,10 +333,8 @@ impl Lsdpack {
                         .with_step_increasing(true)
                         .with_step_time(0),
                 ); // $FF12 <- $18
-                */
             }
             AmpDecPu1 => {
-                /*
                 let base = TONE2_PATTERN.read();
                 TONE2_PATTERN.write(
                     base.with_volume(0)
@@ -279,10 +351,8 @@ impl Lsdpack {
                         .with_step_increasing(true)
                         .with_step_time(0),
                 ); // $FF17 <- $18
-                */
             }
             AmpDecNoi => {
-                /*
                 let base = NOISE_LEN_ENV.read();
                 NOISE_LEN_ENV.write(
                     base.with_volume(0)
@@ -299,51 +369,53 @@ impl Lsdpack {
                         .with_step_increasing(true)
                         .with_step_time(0),
                 ); // $FF21 <- $18
-                */
             }
-            PitchPu0 => {} //self.write_u16le(TONE1_FREQUENCY),
-            PitchPu1 => {} //self.write_u16le(TONE2_FREQUENCY),
+            PitchPu0 => self.write_u16le(TONE1_FREQUENCY),
+            PitchPu1 => self.write_u16le(TONE2_FREQUENCY),
             PitchWav => self.write_u16le(WAVE_FREQ),
             SampleNext => self.write_next_samples(),
 
             // general register writes:
-            Pu0Sweep => {} //unsafe { TONE1_SWEEP.cast() }.write(self.next_byte()),
-            Pu0LengthWave => {} //self.write_lsb(TONE1_PATTERN),
-            Pu0Env => {}   //self.write_msb(TONE1_PATTERN),
-            Pu0PitchLsb => {} //self.write_lsb(TONE1_FREQUENCY),
-            Pu0PitchMsb => {} //self.write_msb(TONE1_FREQUENCY),
-            Pu1LengthWave => {} //self.write_lsb(TONE2_PATTERN),
-            Pu1Env => {}   //self.write_msb(TONE2_PATTERN),
-            Pu1PitchLsb => {} //self.write_lsb(TONE2_FREQUENCY),
-            Pu1PitchMsb => {} //self.write_msb(TONE2_FREQUENCY),
-            WavOnOff => WAVE_BANK.write(WaveBank::new().with_enabled(self.next_byte() != 0)),
+            Pu0Sweep => unsafe { TONE1_SWEEP.cast() }.write(self.next_byte()),
+            Pu0LengthWave => self.write_lsb(TONE1_PATTERN),
+            Pu0Env => {
+                self.next_byte();
+            } //self.write_msb(TONE1_PATTERN),
+            Pu0PitchLsb => self.write_lsb(TONE1_FREQUENCY),
+            Pu0PitchMsb => self.write_msb(TONE1_FREQUENCY),
+            Pu1LengthWave => self.write_lsb(TONE2_PATTERN),
+            Pu1Env => {
+                self.next_byte();
+            } //self.write_msb(TONE2_PATTERN),
+            Pu1PitchLsb => self.write_lsb(TONE2_FREQUENCY),
+            Pu1PitchMsb => self.write_msb(TONE2_FREQUENCY),
+            //WavOnOff => unsafe { WAVE_BANK.cast() }.write(self.next_byte()),
+            WavOnOff => WAVE_BANK.write(
+                WaveBank::new().with_enabled(self.next_byte() != 0), //.with_two_banks(true)
+                                                                     //.with_bank1(false),
+            ),
             WavLength => self.write_lsb(WAVE_LEN_VOLUME),
             WavEnv => self.write_msb(WAVE_LEN_VOLUME),
             WavPitchLsb => self.write_lsb(WAVE_FREQ),
             WavPitchMsb => self.write_msb(WAVE_FREQ),
-            NoiLength => {} //self.write_lsb(NOISE_LEN_ENV),
-            NoiEnv => {}    //self.write_msb(NOISE_LEN_ENV),
-            NoiWave => {}   //self.write_lsb(NOISE_FREQ),
-            NoiTrig => {}   //self.write_msb(NOISE_FREQ),
+            NoiLength => self.write_lsb(NOISE_LEN_ENV),
+            NoiEnv => {
+                self.next_byte();
+            } //self.write_msb(NOISE_LEN_ENV),
+            NoiWave => self.write_lsb(NOISE_FREQ),
+            NoiTrig => self.write_msb(NOISE_FREQ),
             ChannelVolume => self.write_lsb(LEFT_RIGHT_VOLUME),
             Pan => self.write_msb(LEFT_RIGHT_VOLUME),
             SoundOffOn => unsafe { SOUND_ENABLED.cast() }.write(self.next_byte()),
-            WavePattern0 => todo!("WavePattern0"),
-            WavePattern1 => todo!("WavePattern1"),
-            WavePattern2 => todo!("WavePattern2"),
-            WavePattern3 => todo!("WavePattern3"),
-            WavePattern4 => todo!("WavePattern4"),
-            WavePattern5 => todo!("WavePattern5"),
-            WavePattern6 => todo!("WavePattern6"),
-            WavePattern7 => todo!("WavePattern7"),
-            WavePattern8 => todo!("WavePattern8"),
-            WavePattern9 => todo!("WavePattern9"),
-            WavePatternA => todo!("WavePatternA"),
-            WavePatternB => todo!("WavePatternB"),
-            WavePatternC => todo!("WavePatternC"),
-            WavePatternD => todo!("WavePatternD"),
-            WavePatternE => todo!("WavePatternE"),
-            WavePatternF => todo!("WavePatternF"),
+            WavePattern0 | WavePattern1 | WavePattern2 | WavePattern3 | WavePattern4
+            | WavePattern5 | WavePattern6 | WavePattern7 | WavePattern8 | WavePattern9
+            | WavePatternA | WavePatternB | WavePatternC | WavePatternD | WavePatternE
+            | WavePatternF => {
+                let which = cmd as u8 as usize & 0xF;
+                unsafe {
+                    ((0x04000090 + which) as *mut u8).write_volatile(self.next_byte());
+                }
+            }
             _Invalid0B | _Invalid0C | _Invalid0D | _Invalid0E | _Invalid0F | _Invalid15
             | _Invalid1F | _Invalid27 | _Invalid28 | _Invalid29 | _Invalid2A | _Invalid2B
             | _Invalid2C | _Invalid2D | _Invalid2E | _Invalid2F => {