Index: atari_chips/pokeyv2/build.sh
===================================================================
--- atari_chips/pokeyv2/build.sh	(revision 1526)
+++ atari_chips/pokeyv2/build.sh	(revision 1527)
@@ -375,6 +375,7 @@
 				"enable_auto_stereo" => 1,
 				"gtia_audio_bit" => 3,
 				"flash_addr_bits" => 17,
+				"sample_ram_size" => 65536,
 				"cs1_bit" => 20, #force high
 				"a4_bit" => 1, #to access config!
 				"sid_wave_base" => 79872, #"to_integer(unsigned(x\"13800\"))",
@@ -382,6 +383,7 @@
 			"full" =>
 			{
 				"flash_addr_bits" => 17,
+				"sample_ram_size" => 65536,
 				"sid_wave_base" => 79872, #"to_integer(unsigned(x\"13800\"))",
 				"pokeys" => 4,
 				"enable_auto_stereo" => 1,
@@ -464,6 +466,7 @@
 				"enable_spdif" => 0,
 				"enable_ps2" => 0,
 				"flash_addr_bits" => 17,
+				"sample_ram_size" => 65536,
 				"pll_v2" => 0,
 				"a4_bit" => 1,
 				"a5_bit" => 2,
@@ -491,6 +494,7 @@
 				"enable_spdif" => 1,
 				"enable_ps2" => 1,
 				"flash_addr_bits" => 17,
+				"sample_ram_size" => 65536,
 				"pll_v2" => 0,
 				"a4_bit" => 1,
 				"a5_bit" => 2,
@@ -518,6 +522,7 @@
 				"enable_spdif" => 1,
 				"enable_ps2" => 1,
 				"flash_addr_bits" => 17,
+				"sample_ram_size" => 65536,
 				"pll_v2" => 0,
 				"a4_bit" => 1,
 				"a5_bit" => 2,
@@ -708,6 +713,7 @@
 				"enable_spdif" => 1,
 				"enable_ps2" => 1,
 				"flash_addr_bits" => 17,
+				"sample_ram_size" => 65536,
 				"sid_wave_base" => 79872, #"to_integer(unsigned(x\"13800\"))",
 				"a4_bit" => 1,
 				"a5_bit" => 2,
@@ -741,6 +747,7 @@
 				"enable_sample" => 0,
 				"enable_flash" => 1,
 				"flash_addr_bits" => 17,
+				"sample_ram_size" => 65536,
 				"sid_wave_base" => 79872, #"to_integer(unsigned(x\"13800\"))",
 				"a4_bit" => 1,
 				"a5_bit" => 2,
@@ -781,6 +788,7 @@
 				"enable_spdif" => 1,
 				"enable_ps2" => 1,
 				"flash_addr_bits" => 17,
+				"sample_ram_size" => 65536,
 				"sid_wave_base" => 79872, #"to_integer(unsigned(x\"13800\"))",
 				"fancy_switch_bit" => 1,
 				"a4_bit" => 2,
@@ -813,6 +821,7 @@
 				"enable_sample" => 0,
 				"enable_flash" => 1,
 				"flash_addr_bits" => 17,
+				"sample_ram_size" => 65536,
 				"a4_bit" => 2,
 				"a5_bit" => 3,
 				"a6_bit" => 4,
@@ -848,6 +857,7 @@
 				"enable_flash" => 1,
 				"enable_spdif" => 0,
 				"enable_ps2" => 0,
+				#"sample_ram_size" => 46080,
 				"fancy_switch_bit" => 1,
 				"a4_bit" => 2,
 				"a5_bit" => 3,
Index: atari_chips/pokeyv2/m9k_grouped.vhdl
===================================================================
--- atari_chips/pokeyv2/m9k_grouped.vhdl	(nonexistent)
+++ atari_chips/pokeyv2/m9k_grouped.vhdl	(revision 1527)
@@ -0,0 +1,225 @@
+---------------------------------------------------------------------------
+-- (c) 2026 mark watson
+-- I am happy for anyone to use this for non-commercial use.
+-- If my vhdl files are used commercially or otherwise sold,
+-- please contact me for explicit permission at scrameta (gmail).
+-- This applies for source and binary form and derived works.
+--
+-- v2: indexed bank/group selection, avoiding large selected-OR reductions.
+---------------------------------------------------------------------------
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY m9k_grouped IS
+	GENERIC
+	(
+		-- 64K configuration:
+		--   (7*8 + 7)*1024 = 63 KiB in 56 M9Ks using the 9th bit
+		--   +1 KiB in one extra M9K
+		NUM_GROUPS        : natural := 7;
+		EXTRA_RAM_BLOCKS  : natural := 1
+
+		-- 48K configuration:
+		-- NUM_GROUPS        : natural := 5;
+		-- EXTRA_RAM_BLOCKS  : natural := 3
+	);
+	PORT
+	(
+		clock   : IN  std_logic;
+		reset_n : IN  std_logic := '1';
+		data    : IN  std_logic_vector(7 DOWNTO 0);
+		address : IN  std_logic_vector(15 DOWNTO 0);
+		we      : IN  std_logic;
+		q       : OUT std_logic_vector(7 DOWNTO 0)
+	);
+END m9k_grouped;
+
+ARCHITECTURE rtl OF m9k_grouped IS
+	constant ADDR_BITS       : natural := 16;
+	constant RAM_ADDR_BITS   : natural := 10; -- 1 KiB per RAM block
+	constant PAGE_BITS       : natural := ADDR_BITS - RAM_ADDR_BITS; -- 6
+
+	constant BYTE_BITS       : natural := 8;
+	constant WIDE_BIT        : natural := 8;
+
+	constant NORMAL_RAM_BLOCKS : natural := NUM_GROUPS * BYTE_BITS;
+	constant GROUP_RAM_PAGES   : natural := NORMAL_RAM_BLOCKS + NUM_GROUPS;
+	constant TOTAL_RAM_BLOCKS  : natural := NORMAL_RAM_BLOCKS + EXTRA_RAM_BLOCKS;
+	constant TOTAL_MAPPED_PAGES: natural := GROUP_RAM_PAGES + EXTRA_RAM_BLOCKS;
+
+	TYPE ram_data_t IS ARRAY(0 TO TOTAL_RAM_BLOCKS-1) OF std_logic_vector(8 DOWNTO 0);
+
+	SIGNAL q_ram_wide          : ram_data_t;
+	SIGNAL write_data_ram_wide : ram_data_t;
+	SIGNAL sel_ram             : std_logic_vector(0 TO TOTAL_RAM_BLOCKS-1);
+	SIGNAL wide_ram            : std_logic;
+	SIGNAL we_ram              : std_logic;
+
+	SIGNAL address_ram         : std_logic_vector(RAM_ADDR_BITS-1 DOWNTO 0);
+	SIGNAL address_used        : std_logic_vector(ADDR_BITS-1 DOWNTO 0);
+
+	SIGNAL state_next          : std_logic_vector(0 DOWNTO 0);
+	SIGNAL state_reg           : std_logic_vector(0 DOWNTO 0);
+	constant state_idle        : std_logic_vector(0 DOWNTO 0) := "0";
+	constant state_write       : std_logic_vector(0 DOWNTO 0) := "1";
+
+	SIGNAL data_next           : std_logic_vector(7 DOWNTO 0);
+	SIGNAL data_reg            : std_logic_vector(7 DOWNTO 0);
+
+	SIGNAL address_next        : std_logic_vector(ADDR_BITS-1 DOWNTO 0);
+	SIGNAL address_reg         : std_logic_vector(ADDR_BITS-1 DOWNTO 0);
+BEGIN
+
+	-- During idle/read, the RAMs see the live bus address.
+	-- During the write cycle, they see the latched write address.
+	address_used <= address_reg WHEN state_reg = state_write ELSE address;
+	address_ram  <= address_used(RAM_ADDR_BITS-1 DOWNTO 0);
+
+	PROCESS(clock, reset_n)
+	BEGIN
+		IF reset_n = '0' THEN
+			state_reg   <= state_idle;
+			data_reg    <= (others => '0');
+			address_reg <= (others => '0');
+		ELSIF rising_edge(clock) THEN
+			state_reg   <= state_next;
+			data_reg    <= data_next;
+			address_reg <= address_next;
+		END IF;
+	END PROCESS;
+
+	-- Latch write address/data for one-cycle read-modify-write.
+	PROCESS(state_reg, we, data, address, data_reg, address_reg)
+	BEGIN
+		state_next   <= state_reg;
+		data_next    <= data_reg;
+		address_next <= address_reg;
+		we_ram       <= '0';
+
+		CASE state_reg IS
+			WHEN state_idle =>
+				IF we = '1' THEN
+					data_next    <= data;
+					address_next <= address;
+					state_next   <= state_write;
+				END IF;
+
+			WHEN state_write =>
+				we_ram     <= '1';
+				state_next <= state_idle;
+
+			WHEN others =>
+				state_next <= state_idle;
+		END CASE;
+	END PROCESS;
+
+	m9k_loop: FOR i IN 0 TO TOTAL_RAM_BLOCKS-1 GENERATE
+		sample_ram_inst : ENTITY work.generic_ram_infer
+		GENERIC MAP
+		(
+			ADDRESS_WIDTH => RAM_ADDR_BITS,
+			SPACE         => 1024,
+			DATA_WIDTH    => 9
+		)
+		PORT MAP
+		(
+			clock   => clock,
+			reset_n => reset_n,
+			data    => write_data_ram_wide(i),
+			address => address_ram,
+			we      => sel_ram(i) AND we_ram,
+			q       => q_ram_wide(i)
+		);
+	END GENERATE m9k_loop;
+
+	-- Decode only the write-enable selection and the mode.
+	-- Reads use direct indexed muxes rather than sel_ram-masked OR reductions.
+	PROCESS(address_used)
+		VARIABLE page       : natural RANGE 0 TO 2**PAGE_BITS-1;
+		VARIABLE wide_group : natural RANGE 0 TO BYTE_BITS-1;
+		VARIABLE extra      : natural RANGE 0 TO EXTRA_RAM_BLOCKS;
+	BEGIN
+		page       := to_integer(unsigned(address_used(ADDR_BITS-1 DOWNTO RAM_ADDR_BITS)));
+		wide_group := to_integer(unsigned(address_used(12 DOWNTO 10)));
+
+		wide_ram <= '0';
+		sel_ram  <= (others => '0');
+
+		-- 64 KiB example:
+		--   pages 0..55  : normal 8-bit access to RAM blocks 0..55
+		--   pages 56..62 : wide access using bit 8 of RAM blocks 0..55
+		--   page  63     : normal 8-bit access to RAM block 56
+		IF page < NORMAL_RAM_BLOCKS THEN
+			sel_ram(page) <= '1';
+
+		ELSIF page < GROUP_RAM_PAGES THEN
+			wide_ram <= '1';
+			IF wide_group < NUM_GROUPS THEN
+				FOR bt IN 0 TO BYTE_BITS-1 LOOP
+					sel_ram((wide_group * BYTE_BITS) + bt) <= '1';
+				END LOOP;
+			END IF;
+
+		ELSIF page < TOTAL_MAPPED_PAGES THEN
+			extra := page - GROUP_RAM_PAGES;
+			sel_ram(NORMAL_RAM_BLOCKS + extra) <= '1';
+		END IF;
+	END PROCESS;
+
+	-- RAM write data.
+	-- Only the selected RAMs are written, so unselected RAM data inputs are don't-care.
+	-- The assignments below avoid copying every full RAM word back to its input.
+	write_data_loop: FOR i IN 0 TO TOTAL_RAM_BLOCKS-1 GENERATE
+		PROCESS(wide_ram, address_used, data_reg, q_ram_wide)
+			VARIABLE wide_group : natural RANGE 0 TO BYTE_BITS-1;
+		BEGIN
+			wide_group := to_integer(unsigned(address_used(12 DOWNTO 10)));
+
+			write_data_ram_wide(i) <= (others => '0');
+
+			IF wide_ram = '0' THEN
+				-- Normal byte write: replace bits 0..7, preserve the packed wide bit.
+				write_data_ram_wide(i)(BYTE_BITS-1 DOWNTO 0) <= data_reg;
+				write_data_ram_wide(i)(WIDE_BIT) <= q_ram_wide(i)(WIDE_BIT);
+			ELSE
+				-- Wide write: selected group of 8 RAMs stores one bit each in bit 8.
+				-- Preserve the normal byte only for RAMs in the selected group.
+				IF i < NORMAL_RAM_BLOCKS THEN
+					IF wide_group = (i / BYTE_BITS) THEN
+						write_data_ram_wide(i)(BYTE_BITS-1 DOWNTO 0) <= q_ram_wide(i)(BYTE_BITS-1 DOWNTO 0);
+						write_data_ram_wide(i)(WIDE_BIT) <= data_reg(i MOD BYTE_BITS);
+					END IF;
+				END IF;
+			END IF;
+		END PROCESS;
+	END GENERATE write_data_loop;
+
+	-- Read mux. This replaces the previous 57-way selected OR-reduction fabric.
+	PROCESS(address_used, q_ram_wide)
+		VARIABLE page       : natural RANGE 0 TO 2**PAGE_BITS-1;
+		VARIABLE wide_group : natural RANGE 0 TO BYTE_BITS-1;
+		VARIABLE extra      : natural RANGE 0 TO EXTRA_RAM_BLOCKS;
+	BEGIN
+		page       := to_integer(unsigned(address_used(ADDR_BITS-1 DOWNTO RAM_ADDR_BITS)));
+		wide_group := to_integer(unsigned(address_used(12 DOWNTO 10)));
+
+		q <= (others => '0');
+
+		IF page < NORMAL_RAM_BLOCKS THEN
+			q <= q_ram_wide(page)(BYTE_BITS-1 DOWNTO 0);
+
+		ELSIF page < GROUP_RAM_PAGES THEN
+			IF wide_group < NUM_GROUPS THEN
+				FOR bt IN 0 TO BYTE_BITS-1 LOOP
+					q(bt) <= q_ram_wide((wide_group * BYTE_BITS) + bt)(WIDE_BIT);
+				END LOOP;
+			END IF;
+
+		ELSIF page < TOTAL_MAPPED_PAGES THEN
+			extra := page - GROUP_RAM_PAGES;
+			q <= q_ram_wide(NORMAL_RAM_BLOCKS + extra)(BYTE_BITS-1 DOWNTO 0);
+		END IF;
+	END PROCESS;
+
+END rtl;
Index: atari_chips/pokeyv2/pokeymax.vhd
===================================================================
--- atari_chips/pokeyv2/pokeymax.vhd	(revision 1526)
+++ atari_chips/pokeyv2/pokeymax.vhd	(revision 1527)
@@ -59,6 +59,8 @@
 	
 		sid_wave_base : integer := 42496; --to_integer(unsigned(x"a600"));
 
+		sample_ram_size : integer := 43008; --to_integer(unsigned(x"a600"));
+
 		flash_addr_bits : integer := 16;
 
 		ext_clk_enable : integer := 0; -- Use PADDLE(6) for sid clk enable, PADDLE(7) for psg
@@ -251,6 +253,10 @@
 	signal AUDIO_1_SIGMADELTA : std_logic;
 	signal AUDIO_2_SIGMADELTA : std_logic;
 	signal AUDIO_3_SIGMADELTA : std_logic;
+	signal SIGMADELTA_DITHER1 : std_logic_vector(15 downto 0);
+	signal SIGMADELTA_DITHER2 : std_logic_vector(15 downto 0);
+	signal SIGMADELTA_DITHER3 : std_logic_vector(15 downto 0);
+	signal SIGMADELTA_DITHER4 : std_logic_vector(15 downto 0);
 
 	signal KEYBOARD_SCAN : std_logic_vector(5 downto 0);
 	signal IOX_KEYBOARD_RESPONSE : std_logic_vector(1 downto 0);
@@ -1252,11 +1258,48 @@
 		ADPCM_STEP_VALUE => FLASH_DO_SLOW(14 downto 0)
 	);
 
+packed_ram45 : if sample_ram_size=46080 generate 
+	sample_ram_inst : entity work.m9k_grouped
+	GENERIC MAP
+	(
+		 NUM_GROUPS        => 5,
+		 --EXTRA_RAM_BLOCKS => 3
+		 EXTRA_RAM_BLOCKS  => 0
+	)
+	PORT MAP
+	(
+	        clock => clk,
+		reset_n => reset_n,
+		data => write_data,
+		address => sample_ram_address,
+		we => sample_ram_write_enable,
+		q => sample_ram_data
+	);
+end generate;
+
+packed_ram64 : if sample_ram_size=65536 generate 
+	sample_ram_inst : entity work.m9k_grouped
+	--GENERIC MAP
+	--(
+	--	DATA_WIDTH => 8
+	--)
+	PORT MAP
+	(
+	        clock => clk,
+		reset_n => reset_n,
+		data => write_data,
+		address => sample_ram_address,
+		we => sample_ram_write_enable,
+		q => sample_ram_data
+	);
+end generate;
+
+normal_ram : if not(sample_ram_size=65536 or sample_ram_size=46080) generate 
 	sample_ram_inst : entity work.generic_ram_infer
 	GENERIC MAP
 	(
 		ADDRESS_WIDTH => 16,
-		SPACE => 43008,
+		SPACE => SAMPLE_RAM_SIZE,
 		DATA_WIDTH => 8
 	)
 	PORT MAP
@@ -1268,6 +1311,7 @@
 		we => sample_ram_write_enable,
 		q => sample_ram_data
 	);
+end generate;
 
 end generate sample_on;
 		
@@ -1838,13 +1882,24 @@
 	AUDIO_3_SIGNED => AUDIO_MIXED_SIGNED(3)
 );
 
+dac_dithergen : entity work.sigmadelta_dither 
+port map
+(
+  reset_n => reset_n,
+  clk => clk,
+  ENABLE => ENABLE_CYCLE,
+  DITHER_OUT1 => SIGMADELTA_DITHER1,
+  DITHER_OUT2 => SIGMADELTA_DITHER2,
+  DITHER_OUT3 => SIGMADELTA_DITHER3,
+  DITHER_OUT4 => SIGMADELTA_DITHER4
+);
+
 --approx line level by using 5V/4 -> ok 1.25V, should be ok approx
 dac_0 : entity work.filtered_sigmadelta  --pin37
 GENERIC MAP
 (
 	IMPLEMENTATION => sigmadelta_implementation,
-	LOWPASS => lowpass,
-	LFSR_SEED => x"ACE2"
+	LOWPASS => lowpass
 )
 port map
 (
@@ -1852,6 +1907,7 @@
   clk => clk,
   clk2 => CLK116,
   ENABLE_179 => ENABLE_CYCLE,
+  DITHER_IN => SIGMADELTA_DITHER1,
   audin => signed_to_unsigned(AUDIO_MIXED_SIGNED(0)),
   AUDOUT => AUDIO_0_SIGMADELTA
 );
@@ -1862,8 +1918,7 @@
 GENERIC MAP
 (
 	IMPLEMENTATION => sigmadelta_implementation,
-	LOWPASS => lowpass,
-	LFSR_SEED => x"1D2B"
+	LOWPASS => lowpass
 )
 port map
 (
@@ -1871,6 +1926,7 @@
   clk => clk,
   clk2 => CLK106,
   ENABLE_179 => ENABLE_CYCLE,
+  DITHER_IN => SIGMADELTA_DITHER2,
   audin => signed_to_unsigned(AUDIO_MIXED_SIGNED(1)),
   AUDOUT => AUDIO_1_SIGMADELTA
 );
@@ -1885,8 +1941,7 @@
 GENERIC MAP
 (
 	IMPLEMENTATION => sigmadelta_implementation,
-	LOWPASS => lowpass,
-	LFSR_SEED => x"BEEF"
+	LOWPASS => lowpass
 )
 port map
 (
@@ -1894,6 +1949,7 @@
   clk => clk,
   clk2 => CLK116,
   ENABLE_179 => ENABLE_CYCLE,
+  DITHER_IN => SIGMADELTA_DITHER3,
   audin => signed_to_unsigned(AUDIO_MIXED_SIGNED(2)),
   AUDOUT => AUDIO_2_SIGMADELTA
 );
@@ -1902,8 +1958,7 @@
 GENERIC MAP
 (
 	IMPLEMENTATION => sigmadelta_implementation,
-	LOWPASS => lowpass,
-	LFSR_SEED => x"5A3C"
+	LOWPASS => lowpass
 )
 port map
 (
@@ -1911,6 +1966,7 @@
   clk => clk,
   clk2 => CLK106,
   ENABLE_179 => ENABLE_CYCLE,
+  DITHER_IN => SIGMADELTA_DITHER4,
   audin => signed_to_unsigned(AUDIO_MIXED_SIGNED(3)),
   AUDOUT => AUDIO_3_SIGMADELTA
 );
Index: atari_chips/pokeyv2/pokeymaxv1.qsf
===================================================================
--- atari_chips/pokeyv2/pokeymaxv1.qsf	(revision 1526)
+++ atari_chips/pokeyv2/pokeymaxv1.qsf	(revision 1527)
@@ -158,6 +158,7 @@
 set_global_assignment -name VHDL_FILE fir_rom.vhdl
 set_global_assignment -name VHDL_FILE mult_infer.vhdl
 set_global_assignment -name VHDL_FILE generic_ram_infer.vhdl
+set_global_assignment -name VHDL_FILE m9k_grouped.vhdl
 set_global_assignment -name VHDL_FILE simple_low_pass_filter.vhdl
 set_global_assignment -name VHDL_FILE pokey/pokey_poly_17_9.vhdl
 set_global_assignment -name VHDL_FILE pokey/pokey_poly_5.vhdl
Index: atari_chips/pokeyv2/pokeymaxv2.qsf
===================================================================
--- atari_chips/pokeyv2/pokeymaxv2.qsf	(revision 1526)
+++ atari_chips/pokeyv2/pokeymaxv2.qsf	(revision 1527)
@@ -183,6 +183,7 @@
 set_global_assignment -name VHDL_FILE fir_filter.vhdl
 set_global_assignment -name VHDL_FILE fir_rom.vhdl
 set_global_assignment -name VHDL_FILE generic_ram_infer.vhdl
+set_global_assignment -name VHDL_FILE m9k_grouped.vhdl
 set_global_assignment -name VHDL_FILE simple_low_pass_filter.vhdl
 set_global_assignment -name VHDL_FILE pokey/pokey_poly_17_9.vhdl
 set_global_assignment -name VHDL_FILE pokey/pokey_poly_5.vhdl
Index: atari_chips/pokeyv2/pokeymaxv3.qsf
===================================================================
--- atari_chips/pokeyv2/pokeymaxv3.qsf	(revision 1526)
+++ atari_chips/pokeyv2/pokeymaxv3.qsf	(revision 1527)
@@ -177,6 +177,7 @@
 set_global_assignment -name VHDL_FILE fir_filter.vhdl
 set_global_assignment -name VHDL_FILE fir_rom.vhdl
 set_global_assignment -name VHDL_FILE generic_ram_infer.vhdl
+set_global_assignment -name VHDL_FILE m9k_grouped.vhdl
 set_global_assignment -name VHDL_FILE simple_low_pass_filter.vhdl
 set_global_assignment -name VHDL_FILE pokey/pokey_poly_17_9.vhdl
 set_global_assignment -name VHDL_FILE pokey/pokey_poly_5.vhdl
Index: atari_chips/pokeyv2/pokeymaxv4.5.qsf
===================================================================
--- atari_chips/pokeyv2/pokeymaxv4.5.qsf	(revision 1526)
+++ atari_chips/pokeyv2/pokeymaxv4.5.qsf	(revision 1527)
@@ -214,6 +214,7 @@
 set_global_assignment -name VHDL_FILE fir_filter.vhdl
 set_global_assignment -name VHDL_FILE fir_rom.vhdl
 set_global_assignment -name VHDL_FILE generic_ram_infer.vhdl
+set_global_assignment -name VHDL_FILE m9k_grouped.vhdl
 set_global_assignment -name VHDL_FILE simple_low_pass_filter.vhdl
 set_global_assignment -name VHDL_FILE pokey/pokey_poly_17_9.vhdl
 set_global_assignment -name VHDL_FILE pokey/pokey_poly_5.vhdl
