\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
int sb_detect(void)\r
{\r
int i;\r
\r
void *sb_buffer(int *size)\r
{\r
- *size = 65536;\r
- return buffer;\r
+ *size = 32768;\r
+ return (char*)buffer + curblk * 32768;\r
}\r
\r
-void sb_start(int rate, int nchan)\r
+void sb_start(int rate, int bits, int nchan)\r
{\r
uint16_t seg, pmsel;\r
uint32_t addr;\r
addr = (uint32_t)buffer;\r
}\r
\r
- if(!(size = audio_callback(buffer, 65536))) {\r
+ if(!(size = audio_callback(buffer, 32768))) {\r
return;\r
}\r
+ curblk = 1;\r
\r
_disable();\r
if(!prev_intr_handler) {\r
prev_intr_handler = _dos_getvect(IRQ_TO_INTR(irq));\r
}\r
+ printf("setting interrupt vector: %d\n", IRQ_TO_INTR(irq));\r
_dos_setvect(IRQ_TO_INTR(irq), intr_handler);\r
_enable();\r
\r
unmask_irq(irq);\r
\r
- cur_bits = 8;\r
- cur_mode = 0;\r
+ cur_bits = bits;\r
+ cur_mode = 0; /* TODO */\r
if(nchan > 1) {\r
cur_mode |= DSP4_MODE_STEREO;\r
}\r
unsigned char cmd = bits == 8 ? DSP4_START_DMA8 : DSP4_START_DMA16;\r
assert(bits == 8 || bits == 16);\r
\r
+ /*cmd |= DSP4_AUTO | DSP4_FIFO;*/\r
+\r
/* program the DSP to start the DMA transfer */\r
write_dsp(cmd);\r
write_dsp(mode);\r
static void INTERRUPT intr_handler()\r
{\r
int size;\r
+ void *bptr = (unsigned char*)buffer + curblk * 32768;\r
+\r
+ curblk = (curblk + 1) & 1;\r
\r
/* ask for more data */\r
- if(!(size = audio_callback(buffer, 65536))) {\r
+ if(!(size = audio_callback(bptr, 32768))) {\r
sb_stop();\r
} else {\r
- dma_out(dma_chan, (uint32_t)buffer, size, DMA_SINGLE);\r
+ dma_out(dma_chan, (uint32_t)bptr, size, DMA_SINGLE);\r
start_dsp4(cur_bits, cur_mode, size);\r
}\r
\r
\r
void sb_set_output_rate(int rate);\r
\r
-void sb_start(int rate, int nchan);\r
+void sb_start(int rate, int bits, int nchan);\r
void sb_pause(void);\r
void sb_continue(void);\r
void sb_stop(void);\r
\r
struct audrv {\r
void *(*get_buffer)(int *size);\r
- void (*start)(int rate, int nchan);\r
+ void (*start)(int rate, int bits, int nchan);\r
void (*pause)(void);\r
void (*cont)(void);\r
void (*stop)(void);\r
return cbfunc(buf, sz, cbcls);\r
}\r
\r
-void audio_play(int rate, int nchan)\r
+void audio_play(int rate, int bits, int nchan)\r
{\r
- drv.start(rate, nchan);\r
+ drv.start(rate, bits, nchan);\r
}\r
\r
void audio_pause(void)\r
-/*\r
-pcboot - bootable PC demo/game kernel\r
-Copyright (C) 2018 John Tsiombikas <nuclear@member.fsf.org>\r
-\r
-This program is free software: you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation, either version 3 of the License, or\r
-(at your option) any later version.\r
-\r
-This program is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY, without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with this program. If not, see <https://www.gnu.org/licenses/>.\r
-*/\r
#ifndef AUDIO_H_\r
#define AUDIO_H_\r
\r
void audio_set_callback(audio_callback_func func, void *cls);\r
int audio_callback(void *buf, int sz);\r
\r
-void audio_play(int rate, int nchan);\r
+void audio_play(int rate, int bits, int nchan);\r
void audio_pause(void);\r
void audio_resume(void);\r
void audio_stop(void);\r
mask(chan);\r
outp(DMA_CLR_FLIPFLOP(chan), 0);\r
\r
- /* single / block / cascade */\r
- mode = ((flags & 3) << 6) | MODE_CHAN(chan);\r
+ /* first 2 bits of flags correspond to the mode bits 6,7 */\r
+ mode = ((flags & 3) << 6) | dir | MODE_CHAN(chan);\r
if(flags & DMA_DECR) mode |= MODE_DECR;\r
if(flags & DMA_AUTO) mode |= MODE_AUTO;\r
outp(DMA_MODE(chan), mode);\r
if(audio_isplaying()) {\r
audio_stop();\r
} else {\r
- audio_play(22050, 1);\r
+ audio_play(22050, 8, 1);\r
}\r
break;\r
default:\r