#include "dma.h"\r
#include "intr.h"\r
\r
+#define BUFSIZE 16384\r
+\r
#define REG_MIXPORT (base_port + 0x4)\r
#define REG_MIXDATA (base_port + 0x5)\r
#define REG_RESET (base_port + 0x6)\r
static int base_port;\r
static int irq, dma_chan, dma16_chan, dsp_ver;\r
static int dsp4;\r
-static void *buffer;\r
static int xfer_mode;\r
\r
+static void *buffer[2];\r
+static int wrbuf;\r
+\r
static int isplaying;\r
static int cur_bits, cur_mode;\r
-static int curblk;\r
\r
static void (INTERRUPT *prev_intr_handler)();\r
\r
\r
void *sb_buffer(int *size)\r
{\r
- *size = 32768;\r
- return (char*)buffer + curblk * 32768;\r
+ *size = BUFSIZE / 2;\r
+ return buffer[wrbuf];\r
}\r
\r
void sb_start(int rate, int bits, int nchan)\r
uint32_t addr;\r
int size;\r
\r
- if(!buffer) {\r
- /* allocate a 64k-aligned 64k buffer in low memory */\r
- if(!(seg = dpmi_alloc(65536 * 2 / 16, &pmsel))) {\r
+ if(!buffer[0]) {\r
+ /* allocate a 64k-aligned buffer in low memory */\r
+ if(!(seg = dpmi_alloc(BUFSIZE * 2 / 16, &pmsel))) {\r
fprintf(stderr, "sb_start: failed to allocate DMA buffer\n");\r
return;\r
}\r
\r
addr = ((uint32_t)(seg << 4) + 0xffff) & 0xffff0000;\r
printf("DBG aligned: %lx\n", (unsigned long)addr);\r
- buffer = (void*)addr;\r
- } else {\r
- addr = (uint32_t)buffer;\r
+ buffer[0] = (void*)addr;\r
+ buffer[1] = (void*)(addr + BUFSIZE / 2);\r
+ wrbuf = 0;\r
}\r
\r
- if(!(size = audio_callback(buffer, 32768))) {\r
+ if(!(size = audio_callback(buffer[wrbuf], BUFSIZE / 2))) {\r
return;\r
}\r
- curblk = 1;\r
+ addr = (uint32_t)buffer[wrbuf];\r
+ wrbuf ^= 1;\r
\r
_disable();\r
if(!prev_intr_handler) {\r
unmask_irq(irq);\r
\r
cur_bits = bits;\r
- cur_mode = 0; /* TODO */\r
+ cur_mode = bits == 8 ? 0 : DSP4_MODE_SIGNED;\r
if(nchan > 1) {\r
cur_mode |= DSP4_MODE_STEREO;\r
}\r
\r
write_dsp(DSP_ENABLE_OUTPUT);\r
- dma_out(dma_chan, addr, size, DMA_SINGLE);\r
+ dma_out(bits == 8 ? dma_chan : dma16_chan, addr, size, DMA_SINGLE);\r
sb_set_output_rate(rate);\r
- start_dsp4(cur_bits, cur_mode, size);\r
+ start_dsp4(cur_bits, cur_mode, bits == 8 ? size : size / 2);\r
isplaying = 1;\r
}\r
\r
static void INTERRUPT intr_handler()\r
{\r
int size;\r
- void *bptr = (unsigned char*)buffer + curblk * 32768;\r
+ void *bptr = buffer[wrbuf];\r
+ uint32_t addr = (uint32_t)bptr;\r
\r
- curblk = (curblk + 1) & 1;\r
+ wrbuf ^= 1;\r
\r
/* ask for more data */\r
- if(!(size = audio_callback(bptr, 32768))) {\r
+ if(!(size = audio_callback(bptr, BUFSIZE / 2))) {\r
sb_stop();\r
} else {\r
- dma_out(dma_chan, (uint32_t)bptr, size, DMA_SINGLE);\r
- start_dsp4(cur_bits, cur_mode, size);\r
+ if(cur_bits == 8) {\r
+ dma_out(dma_chan, addr, size, DMA_SINGLE);\r
+ start_dsp4(cur_bits, cur_mode, size);\r
+ } else {\r
+ dma_out(dma16_chan, addr, size, DMA_SINGLE);\r
+ start_dsp4(cur_bits, cur_mode, size / 2);\r
+ }\r
}\r
\r
/* acknowledge the interrupt */\r
- inp(REG_INTACK);\r
+ if(cur_bits == 8) {\r
+ inp(REG_INTACK);\r
+ } else {\r
+ inp(REG_INT16ACK);\r
+ }\r
\r
if(irq > 7) {\r
outp(PIC2_CMD, OCW2_EOI);\r