X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dos_sbtest;a=blobdiff_plain;f=src%2Fdma.c;fp=src%2Fdma.c;h=92f0a1b00c6962ac0d111a37f7842271d3b9ccd8;hp=e483002473814b425d1edf77aff9714c923f241f;hb=07c19444f4f2a55abf97d181ab62aeaa51033c62;hpb=01a545fde6dc446fe626382f8bba50b9b7c1a35b diff --git a/src/dma.c b/src/dma.c index e483002..92f0a1b 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1,133 +1,133 @@ -#include -#include "dma.h" - -/* 8bit DMA ports */ -#define DMA_0_ADDR 0x00 -#define DMA_0_COUNT 0x01 -#define DMA_1_ADDR 0x02 -#define DMA_1_COUNT 0x03 -#define DMA_2_ADDR 0x04 -#define DMA_2_COUNT 0x05 -#define DMA_3_ADDR 0x06 -#define DMA_3_COUNT 0x07 -/* 16bit DMA ports */ -#define DMA_4_ADDR 0xc0 -#define DMA_4_COUNT 0xc2 -#define DMA_5_ADDR 0xc4 -#define DMA_5_COUNT 0xc6 -#define DMA_6_ADDR 0xc8 -#define DMA_6_COUNT 0xca -#define DMA_7_ADDR 0xcc -#define DMA_7_COUNT 0xce - -#define DMA_ADDR(c) \ - ((c < 4) ? DMA_0_ADDR + ((c) << 1) : (DMA_4_ADDR + ((c) << 2))) -#define DMA_COUNT(c) \ - ((c < 4) ? DMA_0_COUNT + ((c) << 1) : (DMA_4_COUNT + ((c) << 2))) - -#define DMA8_MASK 0x0a -#define DMA8_MODE 0x0b -#define DMA8_CLR_FLIPFLOP 0x0c -#define DMA8_RESET 0x0d -#define DMA8_MASK_RST 0x0e -#define DMA8_RMASK 0x0f -#define DMA16_MASK 0xd4 -#define DMA16_MODE 0xd6 -#define DMA16_CLR_FLIPFLOP 0xd8 -#define DMA16_RESET 0xda -#define DMA16_MASK_RST 0xdc -#define DMA16_RMASK 0xde - -#define DMA_MASK(c) ((c) < 4 ? DMA8_MASK : DMA16_MASK) -#define DMA_MODE(c) ((c) < 4 ? DMA8_MODE : DMA16_MODE) -#define DMA_CLR_FLIPFLOP(c) ((c) < 4 ? DMA8_CLR_FLIPFLOP : DMA16_CLR_FLIPFLOP) -#define DMA_RESET(c) ((c) < 4 ? DMA8_RESET : DMA16_RESET) -#define DMA_MASK_RST(c) ((c) < 4 ? DMA8_MASK_RST : DMA16_MASK_RST) -#define DMA_RMASK(c) ((c) < 4 ? DMA8_RMASK : DMA16_RMASK) - -#define DMA_0_PAGE 0x87 -#define DMA_1_PAGE 0x83 -#define DMA_2_PAGE 0x81 -#define DMA_3_PAGE 0x82 -#define DMA_4_PAGE 0x8f -#define DMA_5_PAGE 0x8b -#define DMA_6_PAGE 0x89 -#define DMA_7_PAGE 0x8a - -#define MODE_CHAN(x) ((x) & 3) -#define MODE_WRITE 0x04 -#define MODE_READ 0x08 -#define MODE_AUTO 0x10 -#define MODE_DECR 0x20 -#define MODE_SINGLE 0x40 -#define MODE_BLOCK 0x80 -#define MODE_CASCADE 0xc0 - -#define MASK_CHAN(x) ((x) & 3) -#define MASK_DISABLE 0x04 - -#define RMASK_CHAN(x) (1 << ((x) & 3)) - -#define IS_16BIT(c) ((c) >= 4) - -static void dma_io(int chan, uint32_t phyaddr, int size, unsigned int flags, unsigned int dir); -static inline void mask(int chan); -static inline void unmask(int chan); - -static int page_port[] = { - DMA_0_PAGE, DMA_1_PAGE, DMA_2_PAGE, DMA_3_PAGE, - DMA_4_PAGE, DMA_5_PAGE, DMA_6_PAGE, DMA_7_PAGE -}; - -void dma_out(int chan, uint32_t phyaddr, int size, unsigned int flags) -{ - dma_io(chan, phyaddr, size, flags, MODE_READ); -} - -void dma_in(int chan, uint32_t phyaddr, int size, unsigned int flags) -{ - dma_io(chan, phyaddr, size, flags, MODE_WRITE); -} - -static void dma_io(int chan, uint32_t phyaddr, int size, unsigned int flags, unsigned int dir) -{ - unsigned int mode; - int addr_port, count_port; - - addr_port = DMA_ADDR(chan); - count_port = DMA_COUNT(chan); - - mask(chan); - outportb(DMA_CLR_FLIPFLOP(chan), 0); - - /* single / block / cascade */ - mode = ((flags & 3) << 6) | MODE_CHAN(chan); - if(flags & DMA_DECR) mode |= MODE_DECR; - if(flags & DMA_AUTO) mode |= MODE_AUTO; - outportb(DMA_MODE(chan), mode); - - if(IS_16BIT(chan)) { - phyaddr >>= 1; - size >>= 1; - } - - outportb(addr_port, phyaddr & 0xff); - outportb(addr_port, (phyaddr >> 8) & 0xff); - outportb(page_port[chan], (phyaddr >> 16) & 0xff); - - size--; - outportb(count_port, size & 0xff); - outportb(count_port, (size >> 8) & 0xff); - - unmask(chan); -} - -static inline void mask(int chan) -{ - outportb(DMA_MASK(chan), MASK_CHAN(chan) | MASK_DISABLE); -} - -static inline void unmask(int chan) -{ - outportb(DMA_MASK(chan), MASK_CHAN(chan)); -} +#include +#include "dma.h" + +/* 8bit DMA ports */ +#define DMA_0_ADDR 0x00 +#define DMA_0_COUNT 0x01 +#define DMA_1_ADDR 0x02 +#define DMA_1_COUNT 0x03 +#define DMA_2_ADDR 0x04 +#define DMA_2_COUNT 0x05 +#define DMA_3_ADDR 0x06 +#define DMA_3_COUNT 0x07 +/* 16bit DMA ports */ +#define DMA_4_ADDR 0xc0 +#define DMA_4_COUNT 0xc2 +#define DMA_5_ADDR 0xc4 +#define DMA_5_COUNT 0xc6 +#define DMA_6_ADDR 0xc8 +#define DMA_6_COUNT 0xca +#define DMA_7_ADDR 0xcc +#define DMA_7_COUNT 0xce + +#define DMA_ADDR(c) \ + ((c < 4) ? DMA_0_ADDR + ((c) << 1) : (DMA_4_ADDR + ((c) << 2))) +#define DMA_COUNT(c) \ + ((c < 4) ? DMA_0_COUNT + ((c) << 1) : (DMA_4_COUNT + ((c) << 2))) + +#define DMA8_MASK 0x0a +#define DMA8_MODE 0x0b +#define DMA8_CLR_FLIPFLOP 0x0c +#define DMA8_RESET 0x0d +#define DMA8_MASK_RST 0x0e +#define DMA8_RMASK 0x0f +#define DMA16_MASK 0xd4 +#define DMA16_MODE 0xd6 +#define DMA16_CLR_FLIPFLOP 0xd8 +#define DMA16_RESET 0xda +#define DMA16_MASK_RST 0xdc +#define DMA16_RMASK 0xde + +#define DMA_MASK(c) ((c) < 4 ? DMA8_MASK : DMA16_MASK) +#define DMA_MODE(c) ((c) < 4 ? DMA8_MODE : DMA16_MODE) +#define DMA_CLR_FLIPFLOP(c) ((c) < 4 ? DMA8_CLR_FLIPFLOP : DMA16_CLR_FLIPFLOP) +#define DMA_RESET(c) ((c) < 4 ? DMA8_RESET : DMA16_RESET) +#define DMA_MASK_RST(c) ((c) < 4 ? DMA8_MASK_RST : DMA16_MASK_RST) +#define DMA_RMASK(c) ((c) < 4 ? DMA8_RMASK : DMA16_RMASK) + +#define DMA_0_PAGE 0x87 +#define DMA_1_PAGE 0x83 +#define DMA_2_PAGE 0x81 +#define DMA_3_PAGE 0x82 +#define DMA_4_PAGE 0x8f +#define DMA_5_PAGE 0x8b +#define DMA_6_PAGE 0x89 +#define DMA_7_PAGE 0x8a + +#define MODE_CHAN(x) ((x) & 3) +#define MODE_WRITE 0x04 +#define MODE_READ 0x08 +#define MODE_AUTO 0x10 +#define MODE_DECR 0x20 +#define MODE_SINGLE 0x40 +#define MODE_BLOCK 0x80 +#define MODE_CASCADE 0xc0 + +#define MASK_CHAN(x) ((x) & 3) +#define MASK_DISABLE 0x04 + +#define RMASK_CHAN(x) (1 << ((x) & 3)) + +#define IS_16BIT(c) ((c) >= 4) + +static void dma_io(int chan, uint32_t phyaddr, int size, unsigned int flags, unsigned int dir); +static __inline void mask(int chan); +static __inline void unmask(int chan); + +static int page_port[] = { + DMA_0_PAGE, DMA_1_PAGE, DMA_2_PAGE, DMA_3_PAGE, + DMA_4_PAGE, DMA_5_PAGE, DMA_6_PAGE, DMA_7_PAGE +}; + +void dma_out(int chan, uint32_t phyaddr, int size, unsigned int flags) +{ + dma_io(chan, phyaddr, size, flags, MODE_READ); +} + +void dma_in(int chan, uint32_t phyaddr, int size, unsigned int flags) +{ + dma_io(chan, phyaddr, size, flags, MODE_WRITE); +} + +static void dma_io(int chan, uint32_t phyaddr, int size, unsigned int flags, unsigned int dir) +{ + unsigned int mode; + int addr_port, count_port; + + addr_port = DMA_ADDR(chan); + count_port = DMA_COUNT(chan); + + mask(chan); + outp(DMA_CLR_FLIPFLOP(chan), 0); + + /* single / block / cascade */ + mode = ((flags & 3) << 6) | MODE_CHAN(chan); + if(flags & DMA_DECR) mode |= MODE_DECR; + if(flags & DMA_AUTO) mode |= MODE_AUTO; + outp(DMA_MODE(chan), mode); + + if(IS_16BIT(chan)) { + phyaddr >>= 1; + size >>= 1; + } + + outp(addr_port, phyaddr & 0xff); + outp(addr_port, (phyaddr >> 8) & 0xff); + outp(page_port[chan], (phyaddr >> 16) & 0xff); + + size--; + outp(count_port, size & 0xff); + outp(count_port, (size >> 8) & 0xff); + + unmask(chan); +} + +static __inline void mask(int chan) +{ + outp(DMA_MASK(chan), MASK_CHAN(chan) | MASK_DISABLE); +} + +static __inline void unmask(int chan) +{ + outp(DMA_MASK(chan), MASK_CHAN(chan)); +}