fixed DMA bug
authorJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 23 Jan 2019 01:00:11 +0000 (03:00 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 23 Jan 2019 01:00:11 +0000 (03:00 +0200)
src/au_sb.c
src/au_sb.h
src/audio.c
src/audio.h
src/dma.c
src/main.c

index c49b2cf..d733f20 100644 (file)
@@ -89,9 +89,11 @@ static int xfer_mode;
 \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
@@ -178,11 +180,11 @@ void sb_set_output_rate(int rate)
 \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
@@ -205,21 +207,23 @@ void sb_start(int rate, int nchan)
                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
@@ -236,6 +240,8 @@ static void start_dsp4(int bits, unsigned int mode, int num_samples)
        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
@@ -290,12 +296,15 @@ void sb_volume(int vol)
 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
index 0981ba6..4766b44 100644 (file)
@@ -15,7 +15,7 @@ void *sb_buffer(int *size);
 \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
index adb8e3e..88b8400 100644 (file)
@@ -4,7 +4,7 @@
 \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
@@ -47,9 +47,9 @@ int audio_callback(void *buf, int sz)
        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
index 1fde706..c522134 100644 (file)
@@ -1,20 +1,3 @@
-/*\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
@@ -25,7 +8,7 @@ void audio_init(void);
 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
index 92f0a1b..17baead 100644 (file)
--- a/src/dma.c
+++ b/src/dma.c
@@ -100,8 +100,8 @@ static void dma_io(int chan, uint32_t phyaddr, int size, unsigned int flags, uns
        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
index 264c04e..1d148d0 100644 (file)
@@ -43,7 +43,7 @@ int main(int argc, char **argv)
                                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