dosdma.h
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:6k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.     Interface for DMA routines on DOS
  3.     Copyright (C) 1999 by Andrew Zabolotny, <bit@eltech.ru>
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #ifndef __DOSDMA_H__
  17. #define __DOSDMA_H__
  18. #include <pc.h>
  19. #define DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
  20. #define DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
  21. #define DMA1_CMD_REG 0x08 /* command register (w) */
  22. #define DMA1_STAT_REG 0x08 /* status register (r) */
  23. #define DMA1_REQ_REG 0x09 /* request register (w) */
  24. #define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
  25. #define DMA1_MODE_REG 0x0B /* mode register (w) */
  26. #define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
  27. #define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
  28. #define DMA1_RESET_REG 0x0D /* Master Clear (w) */
  29. #define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
  30. #define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
  31. #define DMA2_CMD_REG 0xD0 /* command register (w) */
  32. #define DMA2_STAT_REG 0xD0 /* status register (r) */
  33. #define DMA2_REQ_REG 0xD2 /* request register (w) */
  34. #define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
  35. #define DMA2_MODE_REG 0xD6 /* mode register (w) */
  36. #define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
  37. #define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
  38. #define DMA2_RESET_REG 0xDA /* Master Clear (w) */
  39. #define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
  40. #define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
  41. #define DMA_ADDR_0      0x00 /* DMA address registers */
  42. #define DMA_ADDR_1      0x02
  43. #define DMA_ADDR_2      0x04
  44. #define DMA_ADDR_3      0x06
  45. #define DMA_ADDR_4      0xC0
  46. #define DMA_ADDR_5      0xC4
  47. #define DMA_ADDR_6      0xC8
  48. #define DMA_ADDR_7      0xCC
  49. #define DMA_SIZE_0 0x01 /* DMA transfer size registers */
  50. #define DMA_SIZE_1 0x03
  51. #define DMA_SIZE_2 0x05
  52. #define DMA_SIZE_3 0x07
  53. #define DMA_SIZE_4 0xC2
  54. #define DMA_SIZE_5 0xC6
  55. #define DMA_SIZE_6 0xCA
  56. #define DMA_SIZE_7 0xCE
  57. #define DMA_PAGE_0      0x87 /* DMA page registers */
  58. #define DMA_PAGE_1      0x83
  59. #define DMA_PAGE_2      0x81
  60. #define DMA_PAGE_3      0x82
  61. #define DMA_PAGE_5      0x8B
  62. #define DMA_PAGE_6      0x89
  63. #define DMA_PAGE_7      0x8A
  64. #define DMA_MODE_AUTOINIT 0x10 /* Auto-init mode bit */
  65. #define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
  66. #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
  67. #define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
  68. /* Indexable specific DMA registers */
  69. typedef struct {
  70. unsigned char addr; /* DMA transfer address register */
  71. unsigned char page; /* DMA page register */
  72. unsigned char size; /* DMA transfer size register */
  73. unsigned char mask; /* DMA mask/unmask register */
  74. unsigned char flip; /* DMA flip-flop reset register */
  75. unsigned char mode; /* DMA mode register */
  76. } __dma_regs;
  77. extern __dma_regs dma[8];
  78. /* Enable a specific DMA channel */
  79. static inline void dma_enable(unsigned int channel)
  80. {
  81. outportb(dma[channel].mask, channel & 3);
  82. }
  83. /* Disable a specific DMA channel */
  84. static inline void dma_disable(unsigned int channel)
  85. {
  86. outportb(dma[channel].mask, (channel & 3) | 0x04);
  87. }
  88. /* Clear the 'DMA Flip Flop' flag */
  89. static inline void dma_clear_ff(unsigned int channel)
  90. {
  91. outportb(dma[channel].flip, 0);
  92. }
  93. /* Set mode for a specific DMA channel */
  94. static inline void dma_set_mode(unsigned int channel, char mode)
  95. {
  96. outportb(dma[channel].mode, mode | (channel & 3));
  97. }
  98. /* Set DMA page register */
  99. static inline void dma_set_page(unsigned int channel, char page)
  100. {
  101. if (channel > 3)
  102. page &= 0xfe;
  103. outportb(dma[channel].page, page);
  104. }
  105. /*
  106.   Set transfer address & page bits for specific DMA channel.
  107.   Assumes dma flipflop is clear.
  108. */
  109. static inline void dma_set_addr(unsigned int channel, unsigned int address)
  110. {
  111. unsigned char dma_reg = dma[channel].addr;
  112. dma_set_page(channel, address >> 16);
  113. if (channel <= 3) {
  114. outportb(dma_reg, (address) & 0xff);
  115. outportb(dma_reg, (address >> 8) & 0xff);
  116. } else {
  117. outportb(dma_reg, (address >> 1) & 0xff);
  118. outportb(dma_reg, (address >> 9) & 0xff);
  119. }
  120. }
  121. /*
  122.   Set transfer size for a specific DMA channel.
  123.   Assumes dma flip-flop is clear.
  124. */
  125. static inline void dma_set_count(unsigned int channel, unsigned int count)
  126. {
  127. unsigned char dma_reg = dma[channel].size;
  128. count--; /* number of DMA transfers is bigger by one */
  129. if (channel > 3)
  130. count >>= 1;
  131. outportb(dma_reg, (count) & 0xff);
  132. outportb(dma_reg, (count >> 8) & 0xff);
  133. }
  134. /*
  135.   Query the number of bytes left to transfer.
  136.   Assumes DMA flip-flop is clear.
  137. */
  138. static inline int dma_get_count(unsigned int channel)
  139. {
  140. unsigned char dma_reg = dma[channel].size;
  141. /* using short to get 16-bit wrap around */
  142. unsigned short count;
  143. count = inportb(dma_reg);
  144. count |= inportb(dma_reg) << 8;
  145. count++;
  146. return (channel <= 3) ? count : (count << 1);
  147. }
  148. typedef struct {
  149. unsigned char *linear; /* Linear address */
  150. unsigned long physical; /* Physical address */
  151. unsigned long size; /* Buffer size */
  152. unsigned short selector; /* The selector assigned to this memory */
  153. unsigned char channel; /* The DMA channel */
  154. } dma_buffer;
  155. /* Allocate a block of memory suitable for using as a DMA buffer */
  156. extern dma_buffer *dma_allocate(unsigned int channel, unsigned int size);
  157. /* Deallocate a DMA buffer */
  158. extern void dma_free(dma_buffer * buffer);
  159. /* Start DMA transfer to or from given buffer */
  160. extern void dma_start(dma_buffer * buffer, unsigned long count,
  161.   unsigned char mode);
  162. #endif /* __DOSDMA_H__ */
  163. /* ex:set ts=4: */