Вот в чем суть проблемы. Занимаюсь программированием floppy через порты. Сделал программку чтения сектора. На эмуляторах Virtual PC и Bochs все работает, а на реальном компе выдается ошибка, что сектор не найден. Может быть кто знает возможные причины.
задежка между обращениями к портам есть? P.S. без исходного кода трудно сказать... залей если не секрет
Есть специальный порт для задержки ввода-вывода, а именно EBh. BIOS обожает туда писать... -- О, моя реплика № 200
Я тоже такое написал, Может пригодится! Вот мой код на fasm!!! Код (Text): ;CopyRight by Songoku aka x-goku (songoku{@}tut.by) last_port equ 'lp' ; YOU CAN USE THIS, WENN LAST PORT WAS ABOVE THEN 255 ; IF YOU WANNA USE 0 PORT YOU MAST USE "XOR DX,DX" AND THEN out(x) last_port,y macro outb port,byte { if port eqtype "" if byte in <al> else if byte = 0 xor al,al else mov al,byte end if end if out dx,al else if byte in <al> else if byte = 0 xor al,al else mov al,byte end if end if if port > 255 mov dx,port out dx,al else out port,al end if end if } macro inb port { if port <> last_port if port > 255 mov dx,port in al,dx else in al,port end if else in al,dx end if } DR_A equ 00000000b ; Disk A: DR_B equ 00000001b ; Disk B: ;digital output register DOR DOR equ 3F2h DOR_A equ 00010000b ; Âêëþ÷íèå ìîòîðà DOR_B equ 00100000b ; Âêëþ÷íèå ìîòîðà DOR_DMA equ 00001000b DOR_NONREST equ 00000100b ;Controller enabled ;main status register MSR equ 3F4h MSR_READY equ 10000000b MSR_INPUT equ 01000000b ; With OUT OUTPUT ;data register DATA_REG equ 3F5h CMD_SEEK equ 00001111b ;Seek CMD_READ equ 00000110b ;Read CMD_FLAG_MT equ 10000000b CMD_FLAG_MFM equ 01000000b CMD_FLAG_SK equ 00100000b ;configuration control register (AT) CON_REG equ 3F7h ;Data Transfer Rate TRANSF_RATE_500 equ 00b ;500kbits/s TRANSF_RATE_300 equ 01b ;300kbits/s TRANSF_RATE_250 equ 10b ;250kbits/s ; DMA DMA_CHANEL_0 equ 00h ; Address DMA_CHANEL_0_C equ 01h ; Counter DMA_CHANEL_1 equ 02h ; Address DMA_CHANEL_1_C equ 03h ; Counter DMA_CHANEL_1_SEG equ 83h ; Segment DMA_CHANEL_2 equ 04h ; Address DMA_CHANEL_2_C equ 05h ; Counter DMA_CHANEL_2_SEG equ 81h ; Segment DMA_CHANEL_3 equ 06h ; Address DMA_CHANEL_3_C equ 07h ; Counter DMA_CHANEL_3_SEG equ 82h ; Segment ;---------------------------------- DMA_CMD_MASK equ 0x0A ; Mask ; FLAGS DMA_MASK_CHANEL0 equ 00000000b ; Memory Pointer (Chanel 0) DMA_MASK_CHANEL1 equ 00000001b DMA_MASK_CHANEL2 equ 00000010b ; Floppy DMA_MASK_CHANEL3 equ 00000011b ; Hdd DMA_MASK_SETMASK equ 00000000b ; SET MASK DMA_MASK_DELMASK equ 00000100b ; RESET MASK ;---------------------------------- DMA_CMD_MOD equ 0x0B ; Ðåãèñòð ðåæèìà ; FLAGS DMA_MOD_POINTER equ 00000000b ; Memory Pointer (Chanel 0) DMA_MOD_FLOPPY equ 00000010b ; Chanel 2 DMA_MOD_HDD equ 00000011b ; Chanel 3 DMA_MOD_TEST equ 00000000b ; Test DMA_MOD_WRITE equ 00000100b ; Write To Memory DMA_MOD_READ equ 00001000b ; Read From Memory DMA_MOD_INIT equ 00010000b ; Àâòîèíèöèëèçàöèÿ DMA_MOD_ADDR_INC equ 00000000b ; Óâåëè÷åíèå àäðåñà DMA_MOD_ADDR_DEC equ 00100000b ; Óìåíüøåíèå àäðåñà DMA_MOD_ONCE equ 01000000b ; Îäèíî÷íûé ðåæèì DMA_MOD_BLOCK equ 10000000b ; Áëî÷íûé ðåæèì ;---------------------------------- DMA_CMD_RESET_TR equ 0x0C ; Ñòáðîñ òðèãåðà áàéòîâ ... äëÿ çàãðóçêè 16 áèòíûõ àäðåñîâ DMA_CMD_RESET equ 0x0D ; Reset DMA DMA_CMD_RESER_M equ 0x0F ; Reset MASK ; ; 18 CYLINDERS ; ; ; ; flp_wait: inb MSR test al,MSR_READY jz flp_wait ret ; cl - Drive ; ch - Cylinder ; bl - Head ; bh - Sector to Read ; edi - address ReadSector: mov al,cl or al,DOR_A+DOR_DMA+DOR_NONREST outb DOR,al call flp_wait outb CON_REG,TRANSF_RATE_500 call flp_wait ;DMA outb DMA_CMD_RESET_TR,0 outb DMA_CMD_MOD,DMA_MOD_FLOPPY+DMA_MOD_WRITE+DMA_MOD_ONCE mov ax,1000h;_test;start2 ;ADDRESS outb DMA_CHANEL_2,al mov al,ah outb DMA_CHANEL_2,al mov ax,0 ; SEGMENT outb DMA_CHANEL_2_SEG,al mov ax,511 ; 512 = Size Of Sector outb DMA_CHANEL_2_C,al mov al,ah outb DMA_CHANEL_2_C,al outb DMA_CMD_MASK,DMA_MASK_CHANEL2 ;end of DMA outb DATA_REG,CMD_READ+CMD_FLAG_MFM+CMD_FLAG_SK mov al,cl outb last_port,al ;Floppy mov al,ch outb last_port,al ;Cylinder mov al,bl outb last_port,al ;Head mov al,bh outb last_port,al ;Sector to Read outb last_port,2 ;Sector size (128 * 2^x) -> x = 2 outb last_port,0Fh outb last_port,54H ;Length of GAP 3: outb last_port,0FFh ;Length of data to read call flp_wait inb DATA_REG push eax mov ecx,6 @@: inb last_port loop @B pop eax and al,11000000b movzx eax,al test eax,eax jnz @F push eax mov esi,1000h mov ecx,128 repz movsd pop eax @@: ret
Задержка во флопе организуется через прерывания. Послал команду дождался прерывания прочитал результат. Я развлекался с флоповодом, и у меня всё работало. Наверное даже работает. Если надо могу скинуть сорцы. Только в AT&T синтаксисе. у меня тоже вопрос по поводу флоповода. Приобрёл тут себе новый, и только дома заметил, что в разьёме, куда шлейф втыкать не хватает штырьков, причём всё выглят так как будто так и надо. Флоп замечательно работает, но только до тех пор, пока я не попытаюсь использовать формат диска отличный от стандартного 1440k. Что это может быть? Все дискеты засраны (штуки три я пробовал), или всё дело в отсутсвующих штырьках? Или контроллер помешан на почве 1440k?
Если три способа! 1. Читать память EBh. 2. Обрабатывать прерывание. 3. Использовать эту функцию: Код (Text): flp_wait: inb MSR test al,MSR_READY jz flp_wait ret
rgo > Уже давно такое с флопами, экономия видимо Если нужно работать с нестандартными форматами под NT+ можно попробовать драйвер от OmniFlop.
_S_T_A_S_ я пользую линуховый драйвер флопа, а когда не хватает fdutils. То есть пользовал fdutils. Теперь только /dev/fd0u1440 дееспособен. В честь этого я, обидемшись на флоп, купил себе флеш Но блин, написан загрузчик который из xxdf формата должен грузится. И в процессе моих экспериментов с fdc, флоп сказал прощай. А новый с xxdf работать не хочет (причем проверено на fdutils->xdfformat, xdfcopy). Такой вот облом. Даже убедится не могу что загрузчик написан. А этот омнидиск, может например расформатировать флоп (в отсутсвующими штырьками) на 1760 например? я просто винду снёс, когда место на харде кончилось, и теперь проверить не могу. А на сайте я так и не нашёл слов на этот счёт.
Про 1760 не знаю, последний раз контроллеры дисковода я программировал на Спектруме. И эта прога мне понадобилась что бы прочитать несколько дискет 5'25 под XP. Вот список форматов, которые поддерживает драйвер. Единственно, у проги есть недостаток - требуется регистрация для каждого формата (по мылу), но подходящие s/n несложно находятся, если нет времени ждать. А по поводу недостающих контактов - посмотри номера пинов, может они и не нужны Код (Text): РАСПРЕДЕЛЕНИЕ КОНТАКТОВ РАЗ'ЕМА ВНУТРЕННЕГО ДИСКОВВОДА номера при стандартных ТТЛ-уровнях контактов ─────────────────── ─────────────────── │общий для четных номеров 1-33 │ ├──────────────────────────────────────┤ │не используется 2,4,6│ ├──────────────────────────────────────┤ │индекс 8 │ ├─────────────────────────────────────>┤ │включение двигателя A 10 │ ├<─────────────────────────────────────┤ │выбор привода B 12 │ ├<─────────────────────────────────────┤ │выбор привода A 14 │ ├<─────────────────────────────────────┤ │включение двигателя B 16 │ ├<─────────────────────────────────────┤ │направление(шаг.двиг.) 18 │ ├<─────────────────────────────────────┤ │Шаговый импульс 20 │ Внутренний ├<─────────────────────────────────────┤ адаптер │запись данных 22 │ дисковвод ├<─────────────────────────────────────┤ дисковвода │разрешение записи 24 │ ├<─────────────────────────────────────┤ │нулевая дорожка 26 │ ├─────────────────────────────────────>┤ │защита записи 28 │ ├─────────────────────────────────────>┤ │чтение данных 30 │ ├─────────────────────────────────────>┤ │выбор головки 1 32 │ ├<─────────────────────────────────────┤ │не используется 34 │ ├──────────────────────────────────────┤ ───────────────────│ │───────────────────
Решение проблемы нашел. Пришлось при чтении каждого сектора вставлять команду recalibrate, а потом seek. Знаю, что это коряво. Подскажите когда надо давать команду seek и recalibrate.
valeri рекалибровка нужна один раз, а seek когда с цилиндра на цилиндр переходишь. Линуксовый драйвер флоповода выполняет рекалибровку, только при инициализации драйвера, в случае ошибок и смены носителя. seek каждый раз при смене цилиндра и опять же в случае ошибок. PS. ты точно все байты результата выполнения команды считываешь? _S_T_A_S_ а как при это нумеруются пины? Я придумал восемь способов, и из них один говорит что отсутствует большая часть земли (то есть нечётных контактов). и я думаю что это правильный способ, ибо остальные, по-моему все, какой-нибудь из полезных пинов да выкинут. вот разъём на флопе: Код (Text): 123456789012344678 ------------------ 111111111111111111 100001000010000101 --------[]--------