DMA и Floppy в PM

Тема в разделе "WASM.OS.DEVEL", создана пользователем newinfo2005, 25 июн 2007.

  1. newinfo2005

    newinfo2005 New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2005
    Сообщения:
    3
    Адрес:
    Russia
    Столкнулся с такой проблемой, как можно реализовать работу дисковода в режиме дма находясь в защищенном режиме, очень буду признателен, если мне покажут исходник (лучше на асме).
    Спасибо заранее.
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    пойдет и для PM.
    Код (Text):
    1. use16
    2.  
    3. org 7C00h
    4.  
    5. STACK_BASE  equ 9000h ; заносим в ss
    6. STACK_PTR   equ 9F00h ; заносим в sp
    7. KERNEL_SIZE equ 1024  ; размер ядра в байтах
    8.  
    9. include "..\drivers\floppy\floppy.inc"
    10. include "..\kernel\kernel.inc"
    11.  
    12. start:
    13.     ; отключаем прерывания
    14.     cli
    15.     ; ds = cs = 0
    16.     push cs
    17.     pop ds
    18.     ; настраиваем стек
    19.     mov ax, STACK_BASE
    20.     mov ss, ax
    21.     mov sp, STACK_PTR
    22.     ; ставим свой обработчик IRQ6
    23.     xor cx, cx
    24.     mov word [0Eh * 4], irq6_handler
    25.     mov word [0Eh * 4 + 2], cx
    26.     ; ставим свой обработчик IRQ0
    27.     mov word [08h * 4], irq0_handler
    28.     mov word [08h * 4 + 2], cx
    29.     ; включаем прерывания
    30.     sti
    31.     ; сохраняем адрес DPT, а в es ее сегмент
    32.     mov ax, [78h]
    33.     mov [DPT_table], ax
    34.     mov ax, [78h + 2]
    35.     mov es, ax
    36.     ; врубаем мотор
    37.     call FDD_init
    38.     ; ждём запуска мотора, ~1000ms
    39.     mov bh, 18
    40.     call delay
    41.     ; устанавливаем скорость в 500 кб/с
    42.     mov dx, FLOP_DIR
    43.     xor al, al
    44.     out dx, al
    45.     ; 3 попытки рекалибровать
    46.     mov cl, 3
    47. recalibre_retry:
    48.     ; рекалибровка
    49.     call FDD_recalibrate
    50.     jc error
    51.     ; проверяем успешность опреации
    52.     call FDD_sense_interrupt_status
    53.     jnc recalibre_success
    54.     ; после трех неудачных попыток рекалибровать, выходим
    55.     loop recalibre_retry
    56.     jmp error
    57. recalibre_success:
    58.     ; переходим к первой дорожке
    59.     call FDD_seek
    60.     jc error
    61.     call FDD_sense_interrupt_status
    62.     jc error
    63.     ; задержка для установки головки в новое положение
    64.     mov bh, 1
    65.     call delay
    66.     ; считаем размер сектора в байтах
    67.     mov bx, [DPT_table]
    68.     mov cl, [es: bx + 3]
    69.     mov bx, 128
    70.     shl bx, cl
    71.     ; считаем размер ядра в секторах
    72.     mov ax, KERNEL_SIZE
    73.     xor dx, dx
    74.     div bx
    75.     ; в ch - номер последнего сектора ядра, в cl - первого - 1
    76.     inc al
    77.     mov ch, al
    78.     mov cl, 1
    79.     ; читаем ядро в память
    80.     mov si, KERNEL_BASE
    81. read_kernel:
    82.     call DMA_init
    83.     inc cl
    84.     call FDD_read_sector
    85.     jc error
    86.     add si, bx
    87.     cmp cl, ch
    88.     jne read_kernel
    89.     call FDD_stop
    90.     jmp KERNEL_BASE
    91. error:
    92.     mov si, error_msg
    93.     call putstr
    94. stop:
    95.     jmp stop
    96.  
    97. ; Задержка
    98. ;   bh - на сколько в (1/18.2)с отрезках
    99. delay:
    100.     mov [t_count], 0
    101. delay_loop:
    102.     cmp [t_count], bh
    103.     jne delay_loop
    104.     ret
    105.  
    106. send_EOI:
    107.     push ax
    108.     mov  al, 00100000b
    109.     out  20h, al
    110.     pop ax
    111.     iret
    112.  
    113. ; обработчик прерываний от дисковода
    114. irq6_handler:
    115.     ; ставим флаг того, что подали сигнал
    116.     mov [int_active], 1
    117.     jmp send_EOI
    118.  
    119. ; обработчик прерываний таймера
    120. irq0_handler:
    121.     inc [t_count]
    122.     jmp send_EOI
    123.  
    124. ; Инициализация DMA
    125. DMA_init:
    126.     cli
    127. ;        mov al, 0
    128. ;        out 10, al
    129.     ; команда READ DMA
    130.     mov al, 46h
    131.     ; сброс указателя байта
    132.     out 12, al
    133.     ; утсанавливаем режим работы контроллера DMA
    134.     out 11, al
    135.     ; загружаем линейное смещение нашего буфера, тк ds = 0, то модно избежать лишних вычислений с базой сегмента
    136.     mov ax, si
    137.     ; младший байт адреса буфера
    138.     out 4, al
    139.     mov al, ah
    140.     ; старший байт адреса буфера
    141.     out 4, al
    142.     ; номер страницы, у нас он 0, тк ds = 0, а регистры 16-юитные
    143.     xor al, al
    144.     out 81h, al
    145.     ; загружаем размер данных - 1
    146.     mov ax, bx
    147.     dec ax
    148.     ; младший байт размера данных
    149.     out 5, al
    150.     mov al, ah
    151.     ; старший байт размера данных
    152.     out 5, al
    153.     ; разрешаем наш проинициализированный канал
    154.     mov al, 2
    155.     out 10, al
    156.     sti
    157.     ret
    158.  
    159. ; Инициализация FDD
    160. FDD_init:
    161.     mov dx, FLOP_DOR
    162.     xor ax, ax
    163.     out dx, al
    164.     mov al, 00011100b ; Motor0, Reset, DMA
    165.     out dx, al
    166.     ret
    167.  
    168. ; Остановка FDD
    169. FDD_stop:
    170.     mov al, 00001100b ; DMA, Reset
    171.     mov dx, FLOP_DOR
    172.     out dx, al
    173.     xor al, al
    174.     out dx, al
    175.     ret
    176.  
    177. ; Отсылка байта в порт данных
    178. ;   al - байт для пересылки
    179. FDD_send_byte:
    180.     pusha
    181.     clc
    182.     mov dx, FLOP_MSR
    183.     mov cx, 0FFFFh
    184.     push ax
    185. FDD_send_byte_loop:
    186.     in al, dx
    187.     and al, 11000000b
    188.     cmp al, 10000000b
    189.     je FDD_send_byte_rdy
    190.     loop FDD_send_byte_loop
    191. FDD_send_byte_rdy:
    192.     pop ax
    193.     mov dx, FLOP_FIFO
    194.     out dx, al
    195.     popa
    196.     ret
    197. FDD_send_byte_err:
    198.     stc
    199.     popa
    200.     ret
    201.  
    202. ; Чтение байта из порта данных
    203. ;   al - байт результата
    204. FDD_recv_byte:
    205.     push cx
    206.     clc
    207.     mov dx, FLOP_MSR
    208.     mov cx, 0FFFFh
    209. FDD_recv_byte_loop:
    210.     in al, dx
    211.     and al, 11000000b
    212.     cmp al, 11000000b
    213.     jne FDD_recv_byte_rdy
    214.     loop FDD_recv_byte_loop
    215. FDD_recv_byte_rdy:
    216.     mov dx, FLOP_FIFO
    217.     in al, dx
    218. FDD_recv_byte_exit:
    219.     pop cx
    220.     ret
    221. FDD_recv_byte_err:
    222.     stc
    223.     pop cx
    224.     ret
    225.  
    226. ; Посылаем команду SENSE INTERRUPT STATUS
    227. FDD_sense_interrupt_status:
    228.     ; код команды
    229.     mov al, 00001000b
    230.     call FDD_send_byte
    231.     jc FDD_sense_interrupt_status_exit
    232.     ; читаем st0
    233.     call FDD_recv_byte
    234.     jc FDD_sense_interrupt_status_exit
    235.     and al, 11110000b
    236.     cmp al, 00100000b
    237.     jne FDD_sense_interrupt_status_error
    238.     ; читаем PCN
    239.     call FDD_recv_byte
    240.     jc FDD_sense_interrupt_status_exit
    241.     ; PCN должен быть равен 0
    242.     test al, al
    243.     jnz FDD_sense_interrupt_status_error
    244. FDD_sense_interrupt_status_exit:
    245.     ret
    246. FDD_sense_interrupt_status_error:
    247.     stc
    248.     ret
    249.  
    250. ; Посылаем команду рекалибровки
    251. FDD_recalibrate:
    252.     ; код команды
    253.     mov al, 00000111b
    254.     call FDD_send_byte
    255.     jc FDD_recalibrate_exit
    256.     ; 0 0 0 0 0 0 DS1 DS0
    257.     xor al, al ; 00000000b
    258.     call FDD_send_byte
    259.     jc FDD_recalibrate_exit
    260.     call FDD_wait_end
    261. FDD_recalibrate_exit:
    262.     ret
    263.  
    264. ; Посылаем команду SEEK
    265. FDD_seek:
    266.     mov al, 00001111b
    267.     call FDD_send_byte
    268.     jc FDD_seek_exit
    269.     xor al, al ; 00000000b
    270.     call FDD_send_byte
    271.     jc FDD_seek_exit
    272.     call FDD_send_byte
    273.     jc FDD_seek_exit
    274.     call FDD_wait_end
    275. FDD_seek_exit:
    276.     ret
    277.  
    278. ; Читаем сектор
    279. ;   cl - номер сектора
    280. FDD_read_sector:
    281.     pusha
    282.     ; в bx - адрес DPT
    283.     mov bx, [DPT_table]
    284.     ; READ DATA, Code 1
    285.     mov al, 66h
    286.     call FDD_send_byte
    287.     jc FDD_read_sector_exit
    288.     ; READ DATA, Code 2
    289.     xor al, al
    290.     call FDD_send_byte
    291.     jc FDD_read_sector_exit
    292.     ; Cyl
    293.     call FDD_send_byte
    294.     jc FDD_read_sector_exit
    295.     ; Head
    296.     call FDD_send_byte
    297.     jc FDD_read_sector_exit
    298.     ; Sector
    299.     mov al, cl
    300.     call FDD_send_byte
    301.     jc FDD_read_sector_exit
    302.     ; Sector Size
    303.     mov al, [es: bx + 3]
    304.     call FDD_send_byte
    305.     jc FDD_read_sector_exit
    306.     ; End of track
    307.     mov al, [es: bx + 4]
    308.     call FDD_send_byte
    309.     jc FDD_read_sector_exit
    310.     ; GPL
    311.     mov al, [es: bx + 5]
    312.     call FDD_send_byte
    313.     jc FDD_read_sector_exit
    314.     ; DTL
    315.     mov al, 0FFh
    316.     call FDD_send_byte
    317.     jc FDD_read_sector_exit
    318.     ; ждём когда закончится фаза исполнения
    319.     call FDD_wait_end
    320.     ; ST0
    321.     call FDD_recv_byte
    322.     jc FDD_read_sector_exit
    323.     test al, 11111100b
    324.     jnz FDD_read_sector_error
    325.     ; ST1 & ST2
    326.     xor cx, cx
    327.     mov cl, 2
    328. FDD_read_sector_STX:
    329.     call FDD_recv_byte
    330.     jc FDD_read_sector_exit
    331.     test al, al
    332.     jnz FDD_read_sector_error
    333.     loop FDD_read_sector_STX
    334.     ; C H R N
    335.     mov cl, 4
    336. FDD_read_sector_result:
    337.     call FDD_recv_byte
    338.     loop FDD_read_sector_result
    339. FDD_read_sector_exit:
    340.     popa
    341.     ret
    342. FDD_read_sector_error:
    343.     stc
    344.     popa
    345.     ret
    346.  
    347. ; Ждём завершения опреации
    348. FDD_wait_end:
    349.     mov dx, FLOP_MSR
    350. FDD_wait_end_loop:
    351.     cmp [int_active], 1
    352.     jne FDD_wait_end_loop
    353. FDD_wait_end_exit:
    354.     mov [int_active], 0
    355.     ret
    356.  
    357. putstr:
    358.     lodsb
    359.     or al,al
    360.     jz  putstrd
    361.     mov ah, 0x0E
    362.     mov bx, 0x0007
    363.     int 0x10
    364.     jmp putstr
    365. putstrd:
    366.     retn
    367.  
    368. int_active  db 0
    369. t_count     db 0
    370. DPT_table   dw 0
    371. error_msg   db 'Error',0
    372.  
    373. rb 7C00h + 512 - 2 - $
    374. db 055h,0AAh
     
  3. newinfo2005

    newinfo2005 New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2005
    Сообщения:
    3
    Адрес:
    Russia
    n0name спасибо за код уже начал разбираться, но это я так понял написано на фасме или насме?
    и ещё есть некоторые переменные, которые неописаны в коде, я так понял они на ходятся в этих подключаемых в инклуидах?
    можно их тоже дать?
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    угу, это фасм.

    Код (Text):
    1. FLOP_SRB    equ 3F1h
    2. FLOP_DOR    equ 3F2h  ; 0 0 Motor1 Motor0 DMA Reset 0 Disk
    3. FLOP_TDR    equ 3F3h
    4. FLOP_MSR    equ 3F4h
    5. FLOP_DSR    equ 3F4h
    6. FLOP_FIFO   equ 3F5h
    7. FLOP_DIR    equ 3F7h
    8. FLOP_CCR    equ 3F7h
     
  5. newinfo2005

    newinfo2005 New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2005
    Сообщения:
    3
    Адрес:
    Russia
    n0name Спасибо, выручили.