Универсальная процедура чтения?
Есть одна интересная задача:
можно ли написать универсальную подпрограму для чтения одного любого сектора с дискеты, винта (любого размера), компакта, и, возможно, скайзи?
чем больше тем лучше
желателбно уместить все это в 512 байт
идеальный вариант через порты, хотя принимаются любые варианты (лучше с примерами)
или все же проще на каждое устройство отдельно?
Hi, All
Есть одна интересная задача:
можно ли написать универсальную подпрограму для чтения одного любого сектора с дискеты, винта (любого размера), компакта, и, возможно, скайзи?
чем больше тем лучше
желателбно уместить все это в 512 байт
идеальный вариант через порты, хотя принимаются любые варианты (лучше с примерами)
Ух ты, какая интереснейшая задачка :D. А вот никто тебе тут присылать примеры и не будет. Вы не думайте, что кто-нить будет мучится исходник для кого-то там писать (да еще умещать это в 512 байт, и почему именно 512?). Самому надо думать! Вот если бы ты сказал, например: "Помогите люди, мне курсовую здавать через неделю, а надо через порты научится считывать сектор со всяких там устройств. Я вот с дискетой разобрался, а со SCSI не могу, помогите plizzz!!!! :o ". То может и да ли бы совет какой-то :D. А мучится просто-так не интересно!
или все же проще на каждое устройство отдельно?
Конечно проще :).
я не совсем правильно выразился, меня пока больше интересует вообще возможна ли такая вешь или сам процесс чтения с дискеты, винта и т.д. на столько различаются, что их никак не впихнуть в 512 байт все сразу?
я имел в виду не готовые исходники(они у меня есть, кроме скайзи, но по отдельности :( ), а примерный алгоритм соединения всего этого в одной процедуре.
и если это в принципе не возможно, то я и не буду затеваться на нее, а оставлю все отдельно.
а именно через порты, потому, что мой винт (и не только мой) не поддерживают расширенный инт 13 :(
З.Ы. Только не обижайтесь, но из интересных задач, в этом форуме, по крайней мере для меня, пока только одна - про 16 байт (Hello world!)
за нее я сейчас и сяду
Ok
я не совсем правильно выразился, меня пока больше интересует вообще возможна ли такая вешь или сам процесс чтения с дискеты, винта и т.д. на столько различаются, что их никак не впихнуть в 512 байт все сразу?
Конечно же нельзя их объеденить, потому-что все они имеют разные порты, у некоторых устройств размер сектора не 512 байт (например, насколько я знаю, у CD размер сектора 2048 байт),ну и контроллеры разные у этих устройств (например, чтение с дискеты сектора и винчестера вообще не имеют ничего общего). Можно было бы все процедуры чтения разных устройств объеденить в одну процедуру и в ней делать переход на нужную метку в зависимости от нужного устройства.
Я так и не понял, зачем 512 байт? Хочешь создать универсальный boot sector что ли?
З.Ы. Только не обижайтесь, но из интересных задач, в этом форуме, по крайней мере для меня, пока только одна - про 16 байт (Hello world!)
за нее я сейчас и сяду
Нууу, только не говори, что на пустом месте лабы не дают :). Я же там вроде все расписал, почему это не получится или ты хочешь поспорить :)?
Угу :)
это само собой, буфера можно и после 512 разместить. а порты ведь только базовые нужны (отсчет от них вроде как?), можно их жестко прописать.
у дискет и старых винтов контролеры (вроде :) ) почти одинаковые(<2 Гб, кроме портов). А вот Bus Master видимо притется отдельно делать :(
Чувствую, придется (как я и думал) распихать их для каждого устройства в отдельный файл, а потом делать для разных устройств разные буты.
Тогда такой вопрос: как проще всего их разделить?
может по разным ATA? или больше условно (по размеру)?
P.S. Про Cdrom я слышал, а еще где-нибудь другие размеры секторов встречал (не на старых дискетах :) )?
А насчет как разделить, я тебе отвечу - НЕ ЗНАЮ :).
А зачем все это тебе, что ето ты такое нечистое задумал? Небось свою ось писать захотел :)?
только читый дос
to RelB
В общем файловые системы это уже потом, их процедуры тут ни при чем, да это и не надо (по крайней мере для моей задачи).
нужно читать секторы с любых винтов и любой длины и с любого места.
int 13 Ext моя мама не держит (поменять не предлагать(и маму тоже) :) ), да и не только у меня :( . Вот я и задумал такую страсть через порты сделать.
Видимо зря я так :)
P.S. "А у Вас нет такого же, но с перламутровыми пуговицами?". "Нет?". "Ладно. Будем искать." :)
mov dx,0h ; disk al= 0=floppy
;80h=hd ah=0=golowka(na hdd ili plop)
mov cx,1 ;ah=0 cylindr al=1 sektor
mov bx,7c00h ; buffer
int 13h
mov ax,201h ;procedura czcienija
mov dx,0h ; disk al= 0=floppy
;80h=hd ah=0=golowka(na hdd ili plop)
mov cx,1 ;ah=0 cylindr al=1 sektor
mov bx,7c00h ; buffer
int 13h
Фантомас, ну ты просто радуешь нас своими оригинальными идеями :D.
P.S. Сообщение касается не только этой темы
<<Ну, я не чтобы монстр, просто занимаюсь этим достаточно давно - еще с тех времен, когда с дисководами только через порты и работали (лет этак 15 назад). Так что кое-что рассказать могу.
Вначале напомню, что первый канал IDE-контроллера использует порты с адресами 1F0-1F7, 3F6, 3F7, а
второй - соответственно 170-177, 376, 377. Я буду указывать адреса портов для регистров первого канала (для второго они будут на 80 меньше).
Итак, контроллер IDE использует следующие регистры:
1F0 - регистр данных. Через него идет обмен данными в режиме PIO (то есть при пересылке данных байт за байтом). В режиме прямого доступа (через DMA) он используется самим контроллером и к нему обращаться не следует. Этот регистр 16-битовый, то есть занимает и следующий за ним адрес 1F1, так что нужно использовать целые слова, даже если пересылаются байты (в этом случае старший байт слова равен 0).
1F1 - регистр ошибки. Его биты равны 1 в случае возникновения следующих ситуаций:
бит 0 - ошибка носителя (флэш-памяти);
бит 1 - отсутствует сменный носитель;
бит 2 - аварийное прекращение команды;
бит 3 - запрос на смену носителя;
бит 4 - сектор не найден;
бит 5 - преждевременная смена носителя;
бит 6 - неисправимая ошибка данных;
бит 7 - ошибка по контрольному коду;
Команда диагностики записывает в этот регистр свои коды ошибки:
00 - неисправно устройство 0 (master);
01 - оба устройства исправны;
80 - неисправно устройство 1 (slave);
81 - неисправны оба устройства;
Этот регистр используется также на запись некоторыми командами - для дополнительных параметров.
1F2 - счетчик секторов. Сюда заносится количество передаваемых секторов (от 1 до 255, 0 означает 256). При переходе к очередному сектору он уменьшается на 1, так что после аварийного завершения здесь можно прочитать количество необработанных секторов.
Следующие четыре регистра используются для указания адреса первого сектора при обмене данными. При переходе к очередному сектору сюда заносится его номер, так что при аварийном завершении можно узнать номер первого необработанного сектора. Формат адреса зависит от того, какой используется режим - CHS или LBA. Режим задается битом 6 регистра 1F6 (0 - CHS, 1 - LBA). Биты 5 и 7 этого регистра должны быть всегда равны 1, бит 4 - номер устройства (0 - master, 1 - slave). Остальные 28 бит содержат адрес сектора. В режиме LBA это линейный адрес (от 0 до 2^28- 1), в режиме CHS регистр 1F3 содержит номер сектора, регистры 1F4, 1F5 - номер цилиндра, биты 0- 3 регистра 1F6 - номер головки.
1F7 - регистр состояния. Его биты равны 1 в следующих случаях:
бит 0 - ошибка при выполнении команды;
биты 1 и 2 - не используются;
бит 3 - готовность к обмену данными;
бит 4 - готовность к выполнению следующей команды очереди;
бит 5 - устройство неисправно;
бит 6 - готовность к приему команды;
бит 7 - устройство занято.
3F6 - альтернативный регистр состояния. При его чтении запрос на прерываение не снимается (в отличие от регистра 1F7).
3F7 - не используется
Код очередной команды загружается в регистр команд, имеющий адрес 1F7 - ПОСЛЕ ЗАНЕСЕНИЯ ВСЕХ ДАННЫХ, так как запись кода автоматически вызывает выполнение соответствующей команды.
Кодов команд очень много (из 256 вожможных значений используется чуть меньше половины), поэтому я приведу только основные. Очень не советую экспериментировать с остальными - среди них есть недокументированные коды команд
низкоуровневого форматирования диска и даже полного стирания информации (включая служебную, которую сможет восстановить только фирма-изготовитель). Эти коды, как правило, свои для каждой модели.
Итак, основными (то есть обязательными для всех дисководов) являются следующие команды:
1) Команды настройки и диагностики:
E5 - проверить режим энергопотребления. Код режима возвращается в регистре 1F2 (00 - дежурный режим, 80 - режим ожидания, FF - активное состояние);
90 - диагностика ОБОИХ устройств;
DA - проверка готовности носителя;
EC - идентификация устройства. По этой команде через регистр данных передается 256 слов, содержащих полную информацию об устройстве. Упомяну только самые важные:
слова 1,3,6 - число логических дорожек, головок и секторов на дорожке;
слова с 10 по 19 - серийный номер в ASCII-коде;
слова с 27 по 46 - номер модели в ASCII-коде;
слово 47 - максимальное количество секторов при обмене данными;
слова 54,55,56 - текущее число логических дорожек, головок и секторов на дорожке;
слова 56,57 - текущее число секторов;
слова 60,61 - общее число секторов;
E0/E1/E6 - немедленно перейти в дежурный
режим/режим ожидания/спящий режим;
DE/DF/ED - запереть/отпереть/извлечь носитель (используется для CD-ROM и других сменных носителей, например, ZIP);
2) Команды задания параметров устройства:
E2/E3 - установка временного интервала, по
истечении которого устройство переходит в дежурный режим (standby)/в режим ожидания (idle). Код интервала заносится в регистр 1F2 и может быть следующим:
0 - не переходить;
от 1 до 240 - интервал от 5 секунд до 20 минут с шагом 5 секунд;
от 241 до 251 - интервал от 30 минут до 5.5 часов с шагом 30 минут;
252 - интервал 21 минута;
253 - интервал 8 часов;
254 - не используется;
255 - интервал 21 минута 15 секунд;
91 - установка числа логических секторов на дорожке (регистр 1F2) и максимального логического номера головки (регистр 1F6);
F8/F9 - чтение/установка максимального номера сектора (для режима LBA) или максимальных номеров сектора, цилиндра и головки (для режима CHS);
C6 - установка размера блока данных, передаваемого по одному запросу. Размер (в секторах) заносится в регистр 1F2 и должен быть степенью числа 2;
3) Команды обмена данными:
70 - найти сектор с указанным номером;
E4/E8 - чтение/запись буфера сектора через регистр данных;
C8/CA - чтение/запись секторов в режиме DMA;
C7/CC - чтение/запись секторов в режиме DMA с очередями. В отличие от предыдущей команды, эта допускает освобождение шины, если устройство не готово. Количество передаваемых секторов заносится в регистр 1F1 (а не 1F2), в регистр же 1F2 (старшие 5 бит) заносится тэг команды, позволяющий отличить ее от других аналогичных команд. Всего, таким образом, задается очередь до 32 команд, которые будут выполняться по мере готовности устройства.
Текущее состояние очереди отражается в регистре 1F2:
бит 0 - тип передаваемой информации (0 - данные, 1 - очередная команда);
бит 1 - направление передачи (0 - запись, 1 - чтение);
бит 2 - признак освобождения шины после получения команды;
биты с 3 по 7 - тэг команды, вызвавшей прерывание;
C4/C5 - чтение/запись группы секторов в режиме PIO (через регистр данных). Данные пересылаются блоками, размер которых устанавливается командой C6. Прерывание вырабатывается не после каждого сектора, а после каждого блока;
20/30 - чтение/запись секторов в режиме PIO (прерывание вырабатывается после каждого сектора);
40 - контрольное чтение и проверка секторов (без передачи данных).
Еще раз напомню, что сначала нужно занести в соответствующие регистры все параметры команды, и только потом послать в регистр команд ее код.
Кстати, тут недавно в ответе на вопрос про режим DMA для флоппи порекомендовали книгу Кулакова "Программирование дисковых подсистем". Я к этой рекомендации присоединяюсь - многое я узнал именно оттуда. Вышла она в начале года в "Питер-Пресс". По интерфейсу ATA/ATAPI там отдельная глава (и самая большая из всех), из которой можно узнать гораздо больше.>>
Вот...если это то что надо...Хи...
Видимо зря я это :(
Ладно, тогда 2 вопроса:
1. как все же 2000-е и хр грузятся с любого места?
я от хр бут глянул, так там просто через 2 инт 13
ерунда какая-то :(
2. и как все-таки делить для разных винтов?
по АТА? или просто по размеру? или еще как?
Всего наилучшего!