Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
3.3 KiB

  1. #define DMASTATUSREG 0x8
  2. #define DMA8SINGLEMASKREG 0xa
  3. #define DMA16SINGLEMASKREG 0xd4
  4. #define DMA8MASTERMASKREG 0xf
  5. #define DMA16MASTERMASKREG 0xde
  6. #define DMA8CLEARFLIPFLOP 0xc
  7. #define DMA16CLEARFLIPFLOP 0xd8
  8. #define DMA8BASE 0x0
  9. #define DMA16BASE 0xc0
  10. ULONG page[8] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
  11. VOID __inline UnmaskDmaChannel(ULONG channel)
  12. {
  13. ASSERT ( channel<8 && channel!=4 );
  14. if (channel<4) {
  15. __asm {
  16. mov eax,channel
  17. out DMA8SINGLEMASKREG,al
  18. }
  19. }
  20. else if (channel<8) {
  21. __asm {
  22. mov eax,channel
  23. sub eax,4
  24. out DMA16SINGLEMASKREG,al
  25. }
  26. }
  27. }
  28. VOID __inline MaskDmaChannel(ULONG channel)
  29. {
  30. ASSERT ( channel<8 && channel!=4 );
  31. if (channel<4) {
  32. __asm {
  33. mov eax,channel
  34. or eax,0x4
  35. out DMA8SINGLEMASKREG,al
  36. }
  37. }
  38. else if (channel<8) {
  39. __asm {
  40. mov eax,channel
  41. out DMA16SINGLEMASKREG,al
  42. }
  43. }
  44. }
  45. // This reads the DMA controller mask register.
  46. ULONG __inline ReadDMAMask(VOID)
  47. {
  48. __asm {
  49. xor eax,eax
  50. in al,DMA8MASTERMASKREG
  51. ror eax,4
  52. in al,DMA16MASTERMASKREG
  53. and al,0xf
  54. rol eax,4
  55. }
  56. }
  57. VOID __inline ReadDmaPosition(ULONG channel, PULONG pCurrentDmaPosition)
  58. {
  59. ASSERT ( channel<8 && channel!=4 );
  60. if (channel<4) {
  61. __asm {
  62. // First clear the flip flop.
  63. xor eax,eax
  64. out DMA8CLEARFLIPFLOP, al
  65. // Read low byte and save it away.
  66. mov edx, channel
  67. shl edx, 1
  68. in al, dx
  69. ror eax,8
  70. // Read high byte and save it away.
  71. in al, dx
  72. ror eax,8
  73. // Read page byte.
  74. shl edx, 1
  75. add edx, offset page
  76. mov edx, dword ptr[edx]
  77. in al, dx
  78. ror eax,8
  79. // Read hi-page byte. Ignore if 0xff.
  80. add edx,0x400
  81. in al, dx
  82. sub al, 0xff
  83. jz done8
  84. add al, 0xff
  85. done8:
  86. ror eax,8
  87. mov edx, pCurrentDmaPosition
  88. mov dword ptr [edx], eax
  89. }
  90. }
  91. else if (channel<8) {
  92. __asm {
  93. // First clear the flip flop.
  94. xor eax,eax
  95. out DMA16CLEARFLIPFLOP, al
  96. // Read low byte and save it away.
  97. mov edx, channel
  98. sub edx, 4
  99. shl edx, 2
  100. add edx, DMA16BASE
  101. in al, dx
  102. ror eax,8
  103. // Read high byte and save it away.
  104. // We left shift bottom 16 bits by 1 and or top bit into page.
  105. in al, dx
  106. ror eax,7
  107. mov ah, al
  108. // Read page byte.
  109. mov edx, channel
  110. shl edx, 2
  111. add edx, offset page
  112. mov edx, dword ptr[edx]
  113. in al, dx
  114. // Or in bit 15 of word address and save away page byte.
  115. or al, ah
  116. ror eax,8
  117. // Read hi-page byte. Ignore if 0xff.
  118. add edx,0x400
  119. in al, dx
  120. sub al, 0xff
  121. jz done16
  122. add al, 0xff
  123. done16:
  124. ror eax,8
  125. mov edx, pCurrentDmaPosition
  126. mov dword ptr [edx], eax
  127. }
  128. }
  129. }
  130. VOID __inline ReadDmaCount(ULONG channel, PULONG pCurrentDmaCount)
  131. {
  132. ASSERT ( channel<8 && channel!=4 );
  133. if (channel<4) {
  134. __asm {
  135. // First clear the flip flop.
  136. xor eax,eax
  137. out DMA8CLEARFLIPFLOP, al
  138. // Read low byte and save it away.
  139. mov edx, channel
  140. shl edx, 1
  141. inc edx
  142. in al, dx
  143. ror eax,8
  144. // Read high byte and fixup count.
  145. in al, dx
  146. rol eax,8
  147. mov edx, pCurrentDmaCount
  148. mov dword ptr [edx], eax
  149. }
  150. }
  151. else if (channel<8) {
  152. __asm {
  153. // First clear the flip flop.
  154. xor eax,eax
  155. out DMA16CLEARFLIPFLOP, al
  156. // Read low byte and save it away.
  157. mov edx, channel
  158. sub edx, 4
  159. shl edx, 2
  160. add edx, 2
  161. add edx, DMA16BASE
  162. in al, dx
  163. ror eax,8
  164. // Read high byte and fixup count.
  165. in al, dx
  166. rol eax,9
  167. mov edx, pCurrentDmaCount
  168. mov dword ptr [edx], eax
  169. }
  170. }
  171. }