Index: uspace/drv/audio/sb16/dma.h
===================================================================
--- uspace/drv/audio/sb16/dma.h	(revision 7257eea64d33bbf899e948f1d5528e16064c0dcc)
+++ uspace/drv/audio/sb16/dma.h	(revision f14e6ea74076aac209e1a2569d96de43527101f8)
@@ -41,5 +41,5 @@
 #include <as.h>
 
-#define DMA_ALIGNENT 65536
+#define DMA_ALIGNENT 1024
 
 /** Get physical address translation
@@ -74,6 +74,4 @@
 	if (size > PAGE_SIZE)
 		return NULL;
-	/* Calculate alignment to make sure the block won't cross page
-	 * boundary */
 	return memalign(DMA_ALIGNENT, size);
 }
Index: uspace/drv/audio/sb16/dsp.c
===================================================================
--- uspace/drv/audio/sb16/dsp.c	(revision 7257eea64d33bbf899e948f1d5528e16064c0dcc)
+++ uspace/drv/audio/sb16/dsp.c	(revision f14e6ea74076aac209e1a2569d96de43527101f8)
@@ -42,4 +42,5 @@
 #include "dsp.h"
 
+#define BUFFER_SIZE (PAGE_SIZE / 4)
 
 #ifndef DSP_RETRY_COUNT
@@ -96,16 +97,23 @@
 {
 	assert(dsp);
-	uint8_t *buffer = malloc24(PAGE_SIZE);
+	uint8_t *buffer = malloc24(BUFFER_SIZE);
+	if (buffer == NULL) {
+		ddf_log_error("Failed to allocate buffer.\n");
+		return ENOMEM;
+	}
+
 
 	const uintptr_t pa = addr_to_phys(buffer);
+	assert(pa < (1 << 25));
+//	assert((pa & 0xffff) == 0);
 	/* Set 16 bit channel */
-	const int ret = dma_setup_channel(SB_DMA_CHAN_16, pa, PAGE_SIZE);
+	const int ret = dma_setup_channel(SB_DMA_CHAN_16, pa, BUFFER_SIZE);
 	if (ret == EOK) {
 		dsp->buffer.buffer_data = buffer;
 		dsp->buffer.buffer_position = buffer;
-		dsp->buffer.buffer_size = PAGE_SIZE;
+		dsp->buffer.buffer_size = BUFFER_SIZE;
 		dma_prepare_channel(SB_DMA_CHAN_16, false, true, BLOCK_DMA);
 		/* Set 8bit channel */
-		const int ret = dma_setup_channel(SB_DMA_CHAN_8, pa, PAGE_SIZE);
+		const int ret = dma_setup_channel(SB_DMA_CHAN_8, pa, BUFFER_SIZE);
 		if (ret == EOK) {
 			dma_prepare_channel(
@@ -154,4 +162,16 @@
 }
 /*----------------------------------------------------------------------------*/
+void sb_dsp_interrupt(sb_dsp_t *dsp)
+{
+	assert(dsp);
+	/* We don't really care about the mode of transport, so ack both */
+	if (dsp->version.major >= 4) {
+		/* ACK dma16 transfer interrupt */
+		pio_read_8(&dsp->regs->dma16_ack);
+	}
+	/* ACK dma8 transfer interrupt */
+	pio_read_8(&dsp->regs->dsp_read_status);
+}
+/*----------------------------------------------------------------------------*/
 int sb_dsp_play_direct(sb_dsp_t *dsp, const uint8_t *data, size_t size,
     unsigned sampling_rate, unsigned channels, unsigned bit_depth)
Index: uspace/drv/audio/sb16/dsp.h
===================================================================
--- uspace/drv/audio/sb16/dsp.h	(revision 7257eea64d33bbf899e948f1d5528e16064c0dcc)
+++ uspace/drv/audio/sb16/dsp.h	(revision f14e6ea74076aac209e1a2569d96de43527101f8)
@@ -54,4 +54,5 @@
 
 int sb_dsp_init(sb_dsp_t *dsp, sb16_regs_t *regs);
+void sb_dsp_interrupt(sb_dsp_t *dsp);
 int sb_dsp_play_direct(sb_dsp_t *dsp, const uint8_t *data, size_t size,
     unsigned sample_rate, unsigned channels, unsigned bit_depth);
Index: uspace/drv/audio/sb16/dsp_commands.h
===================================================================
--- uspace/drv/audio/sb16/dsp_commands.h	(revision 7257eea64d33bbf899e948f1d5528e16064c0dcc)
+++ uspace/drv/audio/sb16/dsp_commands.h	(revision f14e6ea74076aac209e1a2569d96de43527101f8)
@@ -142,8 +142,8 @@
 	SINGLE_DMA_16B_DA = 0xb0,     /* Followed by mode, size.low, size.high*/
 	SINGLE_DMA_16B_DA_FIFO = 0xb2,/* mode format is:                      */
-	AUTO_DMA_16B_DA = 0xb4,       /*    0x00 - unsigned mono              */
-	AUTO_DMA_16B_DA_FIFO = 0xb6,  /*    0x10 - signed mono                */
-	SINGLE_DMA_16B_AD = 0xb8,     /*    0x20 - unsigned stereo            */
-	SINGLE_DMA_16B_AD_FIFO = 0xba,/*    0x30 - signed stereo              */
+	AUTO_DMA_16B_DA = 0xb4,       /*    0x00 - unsigned mono 8bit         */
+	AUTO_DMA_16B_DA_FIFO = 0xb6,  /*    0x10 - signed mono 16bit          */
+	SINGLE_DMA_16B_AD = 0xb8,     /*    0x20 - unsigned stereo 8bit       */
+	SINGLE_DMA_16B_AD_FIFO = 0xba,/*    0x30 - signed stereo 16bit        */
 	AUTO_DMA_16B_AD = 0xbc,       /* Size is -1. Terminate by EXIT        */
 	AUTO_DMA_16B_AD_FIFO = 0xbe,  /* or switch to SINGLE_DMA              */
@@ -151,8 +151,8 @@
 	SINGLE_DMA_8B_DA = 0xc0,     /* Followed by mode, size.low, size.high */
 	SINGLE_DMA_8B_DA_FIFO = 0xc2,/* mode format is:                       */
-	AUTO_DMA_8B_DA = 0xc4,       /*    0x00 - unsigned mono               */
-	AUTO_DMA_8B_DA_FIFO = 0xc6,  /*    0x10 - signed mono                 */
-	SINGLE_DMA_8B_AD = 0xc8,     /*    0x20 - unsigned stereo             */
-	SINGLE_DMA_8B_AD_FIFO = 0xca,/*    0x30 - signed stereo               */
+	AUTO_DMA_8B_DA = 0xc4,       /*    0x00 - unsigned mono 8bit          */
+	AUTO_DMA_8B_DA_FIFO = 0xc6,  /*    0x10 - signed mono 16bit           */
+	SINGLE_DMA_8B_AD = 0xc8,     /*    0x20 - unsigned stereo 8bit        */
+	SINGLE_DMA_8B_AD_FIFO = 0xca,/*    0x30 - signed stereo 16bit         */
 	AUTO_DMA_8B_AD = 0xcc,       /* Size is -1. Terminate by EXIT         */
 	AUTO_DMA_8B_AD_FIFO = 0xce,  /* or switch to SINGLE_DMA               */
Index: uspace/drv/audio/sb16/main.c
===================================================================
--- uspace/drv/audio/sb16/main.c	(revision 7257eea64d33bbf899e948f1d5528e16064c0dcc)
+++ uspace/drv/audio/sb16/main.c	(revision f14e6ea74076aac209e1a2569d96de43527101f8)
@@ -80,5 +80,8 @@
 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
 {
-	ddf_log_note("SB16 IRQ handler.\n");
+	assert(dev);
+	sb16_drv_t *sb = dev->driver_data;
+	assert(sb);
+	sb16_interrupt(sb);
 }
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/audio/sb16/registers.h
===================================================================
--- uspace/drv/audio/sb16/registers.h	(revision 7257eea64d33bbf899e948f1d5528e16064c0dcc)
+++ uspace/drv/audio/sb16/registers.h	(revision f14e6ea74076aac209e1a2569d96de43527101f8)
@@ -44,4 +44,6 @@
 	ioport8_t afm_data;
 	ioport8_t mixer_address;
+#define MIXER_IRQ_ADDRESS 0x82 /* The Interrupt Status register, addressed as
+                                * register 82h on the Mixer register map p.27 */
 	ioport8_t mixer_data;
 	ioport8_t dsp_reset;
@@ -56,5 +58,5 @@
 	ioport8_t dsp_read_status; /* Bit 7 */
 #define DSP_READ_READY (1 << 7)
-	ioport8_t __reserved4; /*0xf*/
+	ioport8_t dma16_ack; /*0xf*/
 	ioport8_t cd_command_data;
 	ioport8_t cd_status;
Index: uspace/drv/audio/sb16/sb16.c
===================================================================
--- uspace/drv/audio/sb16/sb16.c	(revision 7257eea64d33bbf899e948f1d5528e16064c0dcc)
+++ uspace/drv/audio/sb16/sb16.c	(revision f14e6ea74076aac209e1a2569d96de43527101f8)
@@ -96,4 +96,25 @@
 int sb16_init_mpu(sb16_drv_t *drv, void *regs, size_t size)
 {
+	drv->mpu_regs = NULL;
 	return ENOTSUP;
 }
+/*----------------------------------------------------------------------------*/
+void sb16_interrupt(sb16_drv_t *drv)
+{
+	assert(drv);
+	ddf_log_note("SB16 interrupt.\n");
+	/* The acknowledgment of interrupts on DSP version 4.xx is different;
+	 * It can contain MPU-401 indicator and DMA16 transfers are acked
+	 * differently */
+	if (drv->dsp.version.major >= 4) {
+		pio_write_8(&drv->regs->mixer_address, MIXER_IRQ_ADDRESS);
+		const uint8_t irq_mask = pio_read_8(&drv->regs->mixer_data);
+		ddf_log_note("SB16 IRQ mask %hhx.\n", irq_mask);
+		/* Third bit is MPU-401 interrupt */
+		if (irq_mask & 0x4) {
+			return;
+		}
+	}
+	sb_dsp_interrupt(&drv->dsp);
+
+}
Index: uspace/drv/audio/sb16/sb16.h
===================================================================
--- uspace/drv/audio/sb16/sb16.h	(revision 7257eea64d33bbf899e948f1d5528e16064c0dcc)
+++ uspace/drv/audio/sb16/sb16.h	(revision f14e6ea74076aac209e1a2569d96de43527101f8)
@@ -53,4 +53,5 @@
 int sb16_init_sb16(sb16_drv_t *drv, void *regs, size_t size);
 int sb16_init_mpu(sb16_drv_t *drv, void *regs, size_t size);
+void sb16_interrupt(sb16_drv_t *drv);
 
 #endif
