Подскажите, каким образом организовать произвольный доступ к секторам 3.5" дискеты через прерывание int 13h. К примеру, если мне необходимо прочитать 20й сектор, какие должны быть параметры: головка, дорожка, сектор ?
В стандартном варианте 2 головки на каждой головке по 80 дорожек на каждой дорожке по 18 секторов. Сектор 512 байт
На дорожке 18 секторов. Мне необходимо прочитать 20й. В каком порядке идет чтение? Сначала читаются все сектора на всех дорожках одной головки, а потом на другой? Или сначала все сектора на одной дорожке, потом на другой головке этой же дорожки? Или как? Понимаю, что вопрос глупый, но разобраться не могу
Методом перебора выяснил, что сначала читаются все сектора нулевой дорожки нулевой головки, потом первой головки, затем читается следующая дорожка нулевой головки и тд Все, что мне нужно было - это вот эта формула: mysector/(2*sectorspertrk), целая часть - Cylinder, остаток - headandsect headandsect/sectorpertrk, целая часть - Head, остаток - Sector
Именно так, дорожка за дорожкой по мере возрастания номеров "цилиндр-головка-сектор". И, если по-хорошему, обязательно исходить из параметров, прочитанных с самой дискеты, а не предполагать, что она содержит заранее определённое число цилиндров и секторов на дорожку, а заодно и то, что является двухсторонней. Хотя, если не извращаться, альтернативных вариантов сейчас не встретишь, но хорошая программа должна корректно вести себя в любом случае, когда это только возможно -- ну или ругаться понятным образом, а не глючить.
Обычно контроллер читает (и буферизует) дорожку за один проход, но секторы могут располагаться в произвольном порядке, в том числе с пропусками и чередованием (interleaving). Нестандартные методы форматирования позволяют иметь секторы различной длины (не говоря уже об играх с Gaps etc). Параметры загрузочной записи не обязательно совпадают с форматированием. Дорожек может быть до 83, но некоторые контроллеры не поддерживают более 80.
конечно, параметр sectorpertrack читается из структуры, которая находится в бутсекторе, да и 2 в моей формуле нужно заменить на numheads, который тоже находится в этой структуре, это уж я так обобщил для стандартных 3.5 дюймовых дискет
j0bana Я написал на всякий случай такое предупреждение Просто бывает неприятно, когда какая-нибудь программа перестаёт работать из-за какой-то мелочи, почему и лучше соблюдать все требования соответствующих стандартов, даже если при написании программы они кажутся необязательными. gazlan Ну, речь-то не о них. Сделать программу, способную работать со всеми мыслимыми способами форматирования дискеты, несколько проблематично Да и смысла никакого нет: нестандартное форматирование употребляется для нестандартных же задач.
X = Linear div SectorsPerTrack Sector = Linear mod SectorsPerTrack + 1 Cylinder = X div Heads Head = X mod Heads Т.е. Sector = остаток + 1
Если на дорожке дискеты 18 секторов (стандартно, хотя бывает и другое), а будем читать сектор #20, то невооруженным глазом видно - надо прочитать сектор №2 на первой головке нулевого цилиндра, что мы сейчас и сделаем: mov ax,201h mov bx,1234h push 5678h pop es mov cx,2 mov dx,100h int 13h jnc good ; (сектор прочитан в ОЗУ по адресу 5678:1234) я здесь и не прочитан, надо опять повторять фрагмент 2...N раз, пока не уйду на метку Good
Думаю, если раз 5 подряд считать не получается, то можно считать сектор повдежденным. Кроме того при работе через прерывания BIOS при каждом ошибочном чтении нужно вызывать функцию сброса, прежде чем повторять попытку чтения.
Phantom_84 Согласен, даже если и c > 3-х не получится - сектор бэд. Обычно после одного/2-х раз возвращает ошибку 06 (была смена дискеты). А сброс давать не обязательно (если только контроллер физически собъется с трека или заклинит - надолго нет готовности самого контроллера).