Leaked source code of windows server 2003
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.

217 lines
5.8 KiB

  1. TITLE Sample 16 Bits DOS application
  2. ;---------------------------------------------------------------;
  3. ;
  4. include 16bits.inc
  5. DOSSEG
  6. .MODEL SMALL
  7. .STACK 100h
  8. .DATA
  9. DMAWriteBuffer label byte
  10. db 64 dup (?)
  11. DMA_BUFFER_SIZE equ $ - DMAWriteBuffer
  12. DMAReadBuffer label byte
  13. db DMA_BUFFER_SIZE dup (?)
  14. MIOPattern label byte
  15. db 00, 0FFh, 0AAh, 055h
  16. MIOPATTERN_SIZE equ $ - MIOPattern
  17. public start
  18. .CODE
  19. start:
  20. jmp short RealStart
  21. OldVector label dword
  22. dd ?
  23. DMACompleted db ?
  24. RealStart:
  25. mov ax,@DATA
  26. mov ds,ax
  27. mov es,ax
  28. assume ds:@DATA, es:@DATA
  29. ;Hook interrupt(DMA terminate count notification)
  30. push ds
  31. mov al, DMA_INTERRUPT
  32. mov ah, 35h
  33. int 21h
  34. mov word ptr cs:OldVector, bx
  35. mov word ptr cs:OldVector + 2, es
  36. mov dx, offset ISRDMACompleted
  37. mov ax, cs
  38. mov ds, ax
  39. mov al, DMA_INTERRUPT
  40. mov ah, 25h
  41. int 21h
  42. pop ds
  43. ;VDD operation.
  44. ;(1). Hook the I/O port.
  45. ;(2). Keep the port status up-to-date if a write operation is performed
  46. ; by 16 bits application(this program).
  47. ;(3). Simulate DMA operation and generate a fake interrupt for 16bits
  48. ; applicatiion if the DMA operation reaches its TC.
  49. ;
  50. ;
  51. ;16bits application
  52. ;(1). Output one byte to the port and then request DMA operation.
  53. ;(2). Wait for DMA operation completed.
  54. ;(3). goto step (1) if there are more data to be transferred.
  55. ;Note that the given I/O must be a R/W port.
  56. ;Here we do a DMA write operation upon I/O mapped I/O
  57. mov cx, DMA_BUFFER_SIZE
  58. mov si, offset DMAWriteBuffer
  59. DMATransferLoop_Fast:
  60. mov dx, IO_PORT_DMA
  61. mov al, cl
  62. out dx, al ;write I/O the current count
  63. cli
  64. mov cs:DMACompleted, FALSE ;reset TC flag
  65. sti
  66. ;channel #1, write op, no auto init, addr inc, single transfer
  67. mov al, 01000101B
  68. call SetupDMAOperation
  69. ;Fire the DMA WRITE operation, this will cause VDD to gain control
  70. ;and start DMA operation.
  71. mov dx, IO_PORT_FIRE_DMA_FAST
  72. out dx, al
  73. ;In real world(there is a real hardware adapter), we won't do this
  74. ;idle loop, rather, we can do something useful(like, read the DMA current
  75. ;count and display the progress and so forth)provided that we can regain
  76. ;control while DMA operation is in progress(VDD spawns a new thread to
  77. ;handle DMA operation and returns to us immediately)
  78. ;
  79. ;Since we are simulating DMA operation without hardware, we always
  80. ;start the DMA operation with transfer count set to 1 byte. In reality
  81. ;this is should not be the case because it will slow down the data transfer.
  82. WaitForDMA_Fast:
  83. cmp cs:DMACompleted, TRUE
  84. jnz WaitForDMA_Fast
  85. inc si
  86. loop DMATransferLoop_Fast
  87. ;
  88. ;Now do a DMA read operation
  89. mov cx, DMA_BUFFER_SIZE
  90. mov si, offset DMAWriteBuffer
  91. mov di, offset DMAReadBuffer
  92. DMATransferLoop_Slow:
  93. ;channel #1, read op, no auto init, addr inc, single transfer
  94. mov al, 01001001B
  95. cli
  96. mov cs:DMACompleted, FALSE
  97. sti
  98. call SetupDMAOperation
  99. ;Fire the DMA READ operation
  100. mov dx, IO_PORT_FIRE_DMA_SLOW
  101. out dx, al
  102. WaitForDMA_Slow:
  103. cmp cs:DMACompleted, TRUE
  104. jne WaitForDMA_Slow
  105. mov dx, IO_PORT_DMA
  106. in al, dx
  107. mov [di], al
  108. inc di ;advance our buffer
  109. inc si ;and the DMA buffer
  110. loop DMATransferLoop_Slow
  111. ;
  112. ;The DMAWriteBuffer and DMAReadBuffer should have the same contents.
  113. ;If they don't, it failed. ....
  114. ;Memory mapped I/O
  115. mov ax, MIO_SEGMENT
  116. mov es, ax
  117. mov bx, MIOPATTERN_SIZE
  118. mov si, offset MIOPattern
  119. MIO_Loop:
  120. cld
  121. lodsb ;get next pattern
  122. mov cx, MIO_PORT_RANGE
  123. mov di, MIO_PORT_FIRST
  124. rep stosb ;fill all I/O with the pattern
  125. mov cx, MIO_PORT_RANGE
  126. dec di
  127. std
  128. repe scasb ;
  129. je @F
  130. ; call ErrorMIO ;if any i/o failed,
  131. @@:
  132. dec bx ;next pattern
  133. jnz MIO_Loop
  134. ;Before terminate, retsore everything we have touched
  135. push ds
  136. lds dx, cs:OldVector
  137. mov al, DMA_INTERRUPT
  138. mov ah, 25h
  139. int 21h
  140. pop ds
  141. mov ah, 04Ch
  142. int 21h
  143. ;-------------------------------------------------------;
  144. ;Setup DMA operation
  145. ;Input: ds:si = seg:offset of memeory address
  146. ; al = DMA mode
  147. ;output: NONE
  148. ;Modified: AX, DX
  149. ;-------------------------------------------------------;
  150. SetupDMAOperation proc
  151. push cx
  152. mov dx, DMA_PORT_FLIPFLOP
  153. out dx, al
  154. mov dx, DMA_PORT_MODE ;more register
  155. out dx, al
  156. mov ax, ds ;transfer address -> page:offset
  157. mov cl, 4 ;page: A16 ~ A19, offset A0 ~ A15
  158. rol ax, cl
  159. mov ch, al
  160. and al, 0F0h
  161. add ax, si
  162. jnc @F
  163. inc ch
  164. @@:
  165. mov dx, DMA_PORT_ADDR
  166. out dx, al ;offset lower byte
  167. mov al, ah
  168. out dx, al ;and higher byte
  169. mov dx, DMA_PORT_PAGE ;page register
  170. mov al, ch
  171. and al, 0Fh ;only 4 bits allowed
  172. out dx, al
  173. mov al, 1 ;single transfer, one byte
  174. mov dx, DMA_PORT_COUNT
  175. out dx, al
  176. dec al
  177. out dx, al ;higher byte set to 0
  178. mov dx, DMA_PORT_REQUEST ;request channel #1
  179. mov al, 00000101B
  180. out dx, al
  181. mov dx, DMA_PORT_SNGLE_MASK ;start DMA transfer
  182. mov al, 00000001B
  183. out dx, al
  184. pop cx
  185. ret
  186. SetupDMAOperation endp
  187. ISRDMACompleted proc far
  188. mov byte ptr DMACompleted, TRUE
  189. mov al, 20h
  190. out 20h, al
  191. out 0A0h, al
  192. iret
  193. ISRDMACompleted endp
  194. END start