Программирование контроллера НГМД 765 и микросхемы прямого доступа к памяти 8237(asm)


Добавил:DMT
Дата создания:24 января 2008, 1:42
Дата обновления:24 января 2008, 1:46
Просмотров:6541 последний сегодня, 10:53
Комментариев: 0
Контроллер НГМД может выполнять 15 операций. Чтение файла состоит в поиске его в каталоге, определении его положения на диске с помощью таблицы размещения файлов и затем наборе операций чтения одного сектора. Эта процедура включает 6 шагов:
1. Включение мотора и короткое ожидание, пока он наберет скорость;
2. Выполнение операции поиска и ожидание прерывания, указывающего на завершение этой операции;
3. Инициализация микросхемы DMA для пересылки данных в память;
4. Посылка команды чтения контроллеру НГМД и ожидание прерывания, указывающего, что пересылка данных завершена;
5. Получение информации о статусе контроллера НГМД;
6. Выключение мотора.

Контроллер НГМД работает через три порта ввода/вывода. На самом деле микросхема имеет больше, чем три регистра, но доступ к большинству из них осуществляется через один порт. Эти три порта такие:
3F2H - регистр цифрового вывода
3F4H - регистр статуса
3F5H - регистр данных

IBM PC XT использует 4-хканальную микросхему DMA 8237. Канал О предназначен для регенерации памяти, он постоянно восстанавливает заряд ячеек оперативной памяти. Канал 2 предназначен для дисковых операций, а два других канала, с номерами 1 и 3, доступны через разъемы расширения для дополнительного оборудования. К сожалению, обмен память-память требует двух каналов и одним из них должен быть канал 0, поэтому такой обмен недоступен на IBM PC XT. Однако, IBM PC AT имеет 7 каналов прямого доступа к памяти и DMA автоматически используется инструкциями MOVS, существенно увеличивая производительность.

Текст программы

Код на ASM
  1. .model tiny
  2. .code
  3. .386
  4. org 100h
  5. start:
  6. ;---выполняем цикл 8 раз
  7. mainloop:
  8. ;---включение мотора
  9. sti
  10. mov dx,3f2h ;регистр цифрового вывода
  11. mov al,28
  12. out dx,al ;в порт 3f2h <- 00011100b
  13. mov cx,50000 ;время ожидания в циклах таймера не менее 23 мкс
  14. mot_d: loop mot_d ;ждем для разогрева мотора
  15.  
  16. ;---выполнение операции поиска дорожки
  17. mov ah,15 ;код команды
  18. call ou_fdc ;в порт 3f5h <- ah (Посылаем контроллеру HГМД)
  19. mov ah,0 ;код дисковода
  20. call ou_fdc
  21. mov ah,nom_dor ;номер дорожки
  22. call ou_fdc
  23. call wa_int ;ожидание прерывания от НГМД
  24. mov cx,50000
  25. wa_set: loop wa_set ;ожидание установки головки
  26.  
  27. ;---инициализации микросхемы DMA
  28. mov al,46h ;код чтения данных контроллера HГМД
  29. out 0bh,al ;заслать в регистр режима работы DMA
  30. out 0ch,al ;сброс внутреннего трифера
  31. ;Вычисляем адрес буфера
  32. lea ax,buf
  33. mov bx,ds ;Помещаем DS в BX
  34. rol bx,4 ;Готовим вращение старшего нибла
  35. mov dl,bl ;Kопируем DL в BL
  36. and dl,0fh ;Чистим старший нибл в DL
  37. and bl,0f0h ;Чистим старший нибл в BX
  38. add ax,bx ;Складываем
  39. jnc no_cry ;Если не было переноса, то # страницы в DL
  40. inc dl ;Увеличиваем DL, если был перенос
  41. no_cry:
  42. ;Посылаем младший байт адреса
  43. out 4,al ;в порт 4h заносим адрес ОЗУ для записи данных
  44. mov al,ah ;Сдвигаем старший байт
  45. out 4,al ;Посылаем младший байт адреса
  46. mov al,dl ;Засылаем номер страницы
  47. out 81h,al ;в порт 81h номер посылаем страницы
  48. ;конец инициализации
  49. mov ax,511 ;Значение счётчика
  50. out 5,al ;в порт 5h заносим количество передоваемых байт
  51. mov al,ah
  52. out 5,al
  53. mov al,2 ;Готовим размещение канала 2
  54. out 0ah,al ;DMA ожидает данные
  55.  
  56. ;---получение указателя на базу диска
  57. mov al,1eh ;Hомер вектора указывающего на таблицу
  58. mov ah,35h ;Hомер функции
  59. int 21h ;Выполнить функцию
  60. ;---посылаем параметры чтения
  61. mov ah,66h ;код чтения одного сектора
  62. call ou_fdc ;посылаем в порт 3F5h
  63. mov ah,0 ;номер головки и накопителя
  64. call ou_fdc
  65. mov ah,nom_dor ;номер дорожки
  66. call ou_fdc
  67. mov ah,0 ;номер головки
  68. call ou_fdc
  69. mov ah,nom_sec ;номер сектора
  70. call ou_fdc
  71. mov ah,es:[bx]+3 ;код размера сектора
  72. call ou_fdc
  73. mov ah,es:[bx]+4 ;номер конца дорожки
  74. call ou_fdc
  75. mov ah,es:[bx]+5 ;длина сдвига
  76. call ou_fdc
  77. mov ah,es:[bx]+6 ;длина данных
  78. call ou_fdc
  79. call wa_int ;ожидание прерывания от НГМД
  80.  
  81. ;---считывание результата
  82. mov cx,7 ;Берём байт 7 статуса
  83. lea bx,sta_buf ;Помещаем в буфер статуса
  84. next:
  85. call in_fdc ;Получаем байт
  86. mov [bx],al ;Помещаем в буфер
  87. inc bx ;Указываем на следующий байт буфера
  88. loop next ;Повторяем операцию
  89.  
  90. ;---выключение мотора
  91. mov dx,3f2h ;адресс регистра цифрового вывода
  92. mov al,12
  93. out dx,al ;в порт 3f2h <- 00001100b
  94. call show_buf ;вывод содержимого буфера на экран
  95. inc nom_sec ;следующий сектор
  96. cmp nom_sec,9
  97. jne mainloop ;считываем следующий сектор дорожки если он <= 8
  98. ret ;возврат управления ДОС
  99.  
  100. ;---ожидание прерывания от НГМД
  101. wa_int proc
  102. ;Управление статусом прерывания 6 в байте статуса BIOS
  103. mov ax,40h ;Сегмент области данных BIOS
  104. mov es,ax ;Помещаем в ES
  105. mov bx,3eh ;Смещение для байта статуса
  106. again:
  107. mov dl,es:[bx] ;Получаем байт
  108. test dl,80h ;Проверяем бит 7
  109. jz again ;До тех пор, пока не установлен
  110. and dl,01111111b ;Сбрасываем бит 7
  111. mov es:[bx],dl ;Заменяем байт статуса
  112. ret ;Kонец процедуры
  113. wa_int endp
  114.  
  115. ;---посылаем байт из ah в порт 3f5h
  116. ou_fdc proc
  117. mov dx,3f4h ;Адрес порта регистра статуса
  118. ke_tr:
  119. in al,dx ;al <- байт состояния НГМД
  120. test al,128 ;бит 7 установлен?
  121. jz ke_tr ;Если нет, продолжать цикл
  122. inc dx ;Указываем на регистр данных
  123. mov al,ah ;Передаваемое значение в AH
  124. out dx,al ;Посылаем значение
  125. ret ;Kонец процедуры
  126. ou_fdc endp
  127.  
  128. ;---получение байта из регистра данных в al
  129. in_fdc proc
  130. mov dx,3f4h ;Адрес порта регистра статуса
  131. ke_tr2:
  132. in al,dx ;Получить значение
  133. test al,128 ;Бит 7 установлен?
  134. jz ke_tr2 ;Если нет, то проверяем снова
  135. inc dx ;Указываем на регистр данных
  136. in al,dx ;Читаем байт из регистра данных
  137. ret ;Kонец процедуры
  138. in_fdc endp
  139.  
  140. ;вывод буфера на экран
  141. show_buf proc
  142. pusha
  143. mov ah,02h
  144. mov dl,10 ;в dl символ, выводимый на стандартный вывод
  145. int 21h
  146. mov dl,13
  147. int 21h
  148. mov dl,nom_sec
  149. add dl,30h
  150. int 21h
  151. mov dl,10
  152. int 21h
  153. mov dl,13
  154. int 21h
  155. xor si,si
  156. mov cx,256
  157. cycle:
  158. mov dl,buf[si]
  159. call showdx
  160. mov dl,' '
  161. int 21h
  162. inc si
  163. loop cycle
  164. popa
  165. show_buf endp
  166.  
  167. ; вывод слова из dl в шестнадцатиричном виде
  168. showdx proc near
  169. push ax
  170. push cx
  171. push dx
  172. mov ah,02h
  173. mov cx,2
  174. loo:
  175. rol dl,4 ;Вращаем младшие 4 бита
  176. push dx
  177. and dl,000fh ;Чистим старший нибл в DL
  178. call show
  179. pop dx
  180. loop loo
  181. pop dx
  182. pop cx
  183. pop ax
  184. ret
  185. show:
  186. cmp dl,9 ;если dl<9 met1
  187. jg met1
  188. add dl,30h
  189. int 21h
  190. ret
  191. met1:
  192. add dl,37h ;в dl текущий символ-переключатель
  193. int 21h
  194. ret
  195. showdx endp
  196.  
  197. buf db 512 dup (?)
  198. sta_buf db 10 dup (?)
  199. nom_sec db 1 ; Здесь номер сектора для чтения
  200. nom_dor db 5 ; Здесь номер дорожки для чтения
  201. end start
При использовании обязательна ссылка на http://DMTSoft.ru
up