-
Notifications
You must be signed in to change notification settings - Fork 0
/
DMA.C
45 lines (38 loc) · 1.7 KB
/
DMA.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include "dma.h"
#include "wss.h"
#include <dos.h>
#define DMAC_MASK_REG 0x0A
#define DMAC_MODE_REG 0x0B
#define DMAC_CLEAR_PTR_REG 0x0C
#define DMAC_MASK_CHANNEL 0x04
#define DMAC_MODE_AUTOINIT_READ 0x58
#define DMAC_MODE_SINGLE_READ 0x48
static const uint8_t dma_page_reg[] = {0x87, 0x83, 0x81, 0x82};
void dma_autoinit_init(uint8_t page, uint16_t offset, uint32_t length) //Program the DMA controller for autoinit transfer
{
outp(DMAC_MASK_REG, DMAC_MASK_CHANNEL | WSS_DMA); //Mask DMA channel
outp(DMAC_CLEAR_PTR_REG, 0x00); //Clear byte pointer
outp(DMAC_MODE_REG, DMAC_MODE_AUTOINIT_READ | WSS_DMA); //Set autoinit mode
outp(WSS_DMA << 1, offset & 0xFF); //Write the offset
outp(WSS_DMA << 1, offset >> 8);
outp((WSS_DMA << 1) + 1, (length - 1) & 0xFF); //Set the block length
outp((WSS_DMA << 1) + 1, ((length - 1) >> 8) & 0xFF);
outp(dma_page_reg[WSS_DMA], page); //Write the page
outp(DMAC_MASK_REG, WSS_DMA); //Unmask DMA channel
}
void dma_single_init(uint8_t page, uint16_t offset, uint32_t length) //Program the DMA controller for single cycle transfer
{
outp(DMAC_MASK_REG, DMAC_MASK_CHANNEL | WSS_DMA); //Mask DMA channel
outp(DMAC_CLEAR_PTR_REG, 0x00); //Clear byte pointer
outp(DMAC_MODE_REG, DMAC_MODE_SINGLE_READ | WSS_DMA); //Set autoinit mode
outp(WSS_DMA << 1, offset & 0xFF); //Write the offset
outp(WSS_DMA << 1, offset >> 8);
outp((WSS_DMA << 1) + 1, (length - 1) & 0xFF); //Set the block length
outp((WSS_DMA << 1) + 1, ((length - 1) >> 8) & 0xFF);
outp(dma_page_reg[WSS_DMA], page); //Write the page
outp(DMAC_MASK_REG, WSS_DMA); //Unmask DMA channel
}
void dma_release(void)
{
outp(DMAC_MASK_REG, DMAC_MASK_CHANNEL | WSS_DMA); //Mask DMA channel
}