Тестирование контроллера прямого доступа до оперативной памяти (DMA)

Тема в разделе "WASM.ASSEMBLER", создана пользователем frame, 14 фев 2008.

  1. frame

    frame New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    6
    Эта програмка по утверждению знакомого работала нормально - но как видите он мне ее снизу "отрубал". :dntknw: .Теперь незнаю что там было. помогите кто чем может - может чем-то еще ее дополнить.
    Вот программа:


    Код (Text):
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <conio.h>
    4. #include <dos.h>
    5. #include "sysp.h"
    6.  
    7. #define CYL 0
    8.  
    9. void main(void);
    10. void fdc_out(unsigned char byte);
    11. int  fdc_inp(void);
    12. void int_wait(void);
    13. void dma_init(char *);
    14.  
    15. void main(void) {
    16.  
    17.         unsigned i;
    18.         long l;
    19.         char buffer[512];
    20.         char status[7], main_status;
    21.         DPT _far *fdpt;
    22.         FILE *sect;
    23.  
    24.         printf("\n"
    25.                  "\nРабота с контроллером НГМД"
    26.                  "\n);
    27.  
    28. // Эта программа предназначена только для IBM AT
    29.  
    30.         if(pc_model() != 0xfc) {
    31.                 printf("Эта программа предназначена только для IBM AT\n");
    32.                 exit(-1);
    33.         }
    34.  
    35. // Открываем файл, в который будем записывать
    36. // содержимое самого первого сектора на дискете
    37.  
    38.         sect = fopen("!sector.dat","wb+");
    39.  
    40. // Устанавливаем указатель на таблицу
    41. // параметров дискеты
    42.  
    43.         fdpt = get_dpt();
    44.  
    45. // Включаем мотор дисковода А:
    46. // Перед этим разрешаем прерывания
    47.  
    48.      _enable();
    49.         outp(0x3F2, 0x1C);
    50.  
    51. // Выполняем задержку для разгона двигателя
    52.  
    53.         for(l=0;l<200000;l++);
    54.  
    55. // Показываем содержимое регистра основного
    56. // состояния контроллера
    57.  
    58.         printf("Мотор включен.\t\t");
    59.         printf("Основное состояние: %02.2X\n",inp(0x3F4));
    60.  
    61. // Перед чтением сектора необходимо установить
    62. // головку на нужную дорожку, в нашем случае это
    63. // дорожка с номером CYL.
    64.  
    65. // Выдаем контроллеру команду "Поиск"
    66.  
    67.         fdc_out(0xf);
    68.  
    69. // Для команды "Поиск" требуется два байта параметров:
    70. // номер головки/номер накопителя и номер дорожки.
    71. // Мы работаем с нулевой головкой накопителя А:,
    72. // поэтому первый параметр равен 0, второй - CYL
    73.  
    74.         fdc_out(0);
    75.         fdc_out(CYL);
    76.  
    77. // Показываем содержимое регистра основного
    78. // состояния контроллера
    79.  
    80.         printf("\n<<<Поиск>>> \t\t");
    81.         printf("Основное состояние: %02.2X\n",inp(0x3F4));
    82.  
    83. // Ожидаем прерывание по завершению операции
    84.  
    85.         int_wait();
    86.  
    87. // Задержка для позиционирования головки
    88.  
    89.         for(l=0;l<20000;l++);
    90.  
    91. // Для проверки результата выполнения команды
    92. // "Поиск" выдаем контроллеру команду
    93. // "Чтение состояния прерывания"
    94.  
    95. // Выводим содержимое регистра состояния
    96. // ST0  и номер дорожки после выполнения команды
    97. // "Поиск" PCN
    98.  
    99.         fdc_out(0x8);
    100.         printf("Состояние прерывания:\t");
    101.         printf(" ST0: %02.2X, \t", fdc_inp());
    102.         printf("PCN: %02.2X\n", fdc_inp());
    103.  
    104. // Для более глубокой диагностики состояния
    105. // контроллера выдаем контроллеру команду
    106. // "Чтение состояния накопителя", выводим
    107. // содержимое регистра состояния ST3
    108.  
    109.         fdc_out(4);
    110.         fdc_out(0);
    111.         printf("Состояние накопителя:\t ST3: %02.2X\n",fdc_inp());
    112.  
    113. // Устанавливаем скорость передачи данных 500 Кбайтов/с,
    114. // это значение может различаться для разных типов дискет
    115.  
    116.         outp(0x3F7, 0);
    117.  
    118. // Инициализация канала прямого
    119. // доступа к памяти
    120.  
    121.         dma_init(buffer);
    122.  
    123. // Выдаем команду "Чтение данных"
    124.  
    125.         fdc_out(0x66);
    126.         fdc_out(0x0);     // накопитель 0, головка 0
    127.  
    128.         fdc_out(CYL);     // цилиндр CYL
    129.         fdc_out(0);       // головка 0
    130.         fdc_out(1);       // номер сектора - 1
    131.  
    132. // Передаем контроллеру технические параметры
    133. // дисковода, берем их из таблицы параметров дискеты.
    134. // Это такие параметры:
    135. //    - размер сектора;
    136. //    - номер последнего сектора на дорожке;
    137. //    - размер промежутка;
    138. //    - число считываемых/записываемых байтов
    139.  
    140.         fdc_out(fdpt->sec_size);
    141.         fdc_out(fdpt->eot);
    142.         fdc_out(fdpt->gap_rw);
    143.         fdc_out(fdpt->dtl);
    144.  
    145. // Ожидаем прерывание по завершению операции
    146.  
    147.         int_wait();
    148.  
    149. // Считываем и выводим на экран байты результата
    150. // операции "Чтение данных"
    151.  
    152.         printf("\n<<<Чтение сектора>>> \n");
    153.         printf("   Байты состояния (ST0,ST1,ST2,C,H,R,N):\n");
    154.  
    155.         for(i=0; i<7; i++) printf("%02.2X\t", (char) fdc_inp());
    156.         printf("\n");
    157.  
    158. // Выводим содержимое считанного сектора в файл
    159.  
    160.         for(i=0; i<512; i++) fputc(buffer[i],sect);
    161.         fclose(sect);
    162.  
    163. // Выключаем мотор
    164.  
    165.         outp(0x3F2, 0xC);
    166. }
    167.  
    168.  
    169.  
    170. // Вывод байта в контроллер дисковода
    171.  
    172. void fdc_out(unsigned char parm) {
    173.  
    174.         _asm {
    175.                 mov   dx,3F4h     // Порт основного состояния
    176. loop_fdc_out:
    177.  
    178.                 in    al,dx
    179.                 test  al,80h      // Проверяем готовность
    180.                 jz loop_fdc_out   //   контроллера
    181.  
    182.                 inc   dx          // Выводим байт в порт данных
    183.                 mov   al, parm    //   контроллера
    184.                 out   dx, al
    185.         }
    186. }
    187.  
    188. // Ввод байта из порта данных контроллера дисковода
    189.  
    190. int fdc_inp(void) {
    191.  
    192.         _asm {
    193.                 mov   dx,3F4h     // Порт основного состояния
    194. loop_fdc_inp:
    195.                 in    al,dx
    196.                 test  al,80h      // Проверяем готовность
    197.                 jz loop_fdc_inp   //   контроллера
    198.  
    199.                 inc   dx          // Введенный байт записываем
    200.                 in    al, dx      // в регистр AX
    201.         }
    202. }
    203.  
    204. // Ожидание прерывания от контроллера
    205.  
    206. void int_wait(void) {
    207.  
    208. // Разрешаем прерывания
    209.  
    210.         _enable();
    211.         _asm {
    212.                 mov   ax,40h         // После прихода прерывания
    213.                 mov   es,ax          // программа обработки прерывания
    214.                 mov   bx,3Eh         // устанавливает в 1 старший бит
    215. wait_loop:                     // байта в области данных BIOS
    216.                 mov   dl,es:[bx]     // по адресу 0040:003E.
    217.                 test  dl,80h         // Мы ждем, когда
    используем тег [ code ]!
     
  2. frame

    frame New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    6
    Кто нибудь делал программы связаные с DMA (ПДП)?Знаю точно что контроллер ПДП имеет 4(если не ошибаюсь) регистра - адрес источника; адрес получателя; адрес с которого начинается считывание и еще что-то. Я ассемблере пока неочень, но хотелось бы во всем разобраться...
     
  3. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    frame
    В аттаче файл с небольшой теоретической частью про DMA и примером вывода звука через DMA в SoundBlaster писалось под DOS более 10 лет назад сейчас если и будет работать то только в "чистом DOS'е" Перезалил... Какие-то траблы с закачкой, переделал doc в txt форматирование потеряно, за то размер уменьшился:)
     
  4. frame

    frame New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    6
    Mikl__ А ты неподскажеш откуда этот материальчик
    З.Ы. Архив обрезаный - может перезакачаеш если не сложно.

    Я так понял DMA используется только для передачи звука и данных со внешних хранителей. Если не так поправте.
     
  5. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    frame
    Сам писал;)
    Здесь пример вывода звука на SoundBlaster через DMA
     
  6. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    frame
    Какие-то траблы с аттачами, вроде бы и размер маленький, а снова взяв архив с сайта я уже не могу его открыть. Напиши мне в почту я переправлю письмо с прикрепленными файлами
     
  7. frame

    frame New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    6
    Еще вопрос:Откуда мне взять эти модули?(Смотреть в начале текста программы)
    <stdio.h>
    <stdlib.h>
    <conio.h>
    <dos.h>
    "sysp.h"
     
  8. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    frame
    DMA использовался в DOS'е для фоновой печати, передача данных со сканера, передача данных с/из звуковой платы. Как используется сейчас не знаю.
    Как читаются архивы?
     
  9. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    для винтов встречал код юзающий DMA в сорцах драйверов.
     
  10. frame

    frame New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    6
    Я уже нашел кое-что, кстатти и в статтях WASM.RU.
    Вот ссылочка, посмотрите если заинтересовало
    http://www.wasm.ru/article.php?article=atazen02
    http://techn.sstu.ru/TFI/site_tfi/TFI/PVS/material/Terin/mpbasics/hardware/mpbasics/2/2.html