простите, что пишу =/ нужна помощь, а в Ассе я новичёк мне нужно написать прогу, которая проверяет наличие дискеты в приводе и если дискета есть, то вывести информацию о ней:кол-во сторон, кол-во дорожек, кол-во слотов на дорожке Code (Text): .model small .stack 100h .data a dw 0 .code start: mov ax,@data mov ds,ax mov ah,32h mov dl,1 int 21h ;конец cmp al,0 jnz exit exit: mov ax,4c00h int 21h end start end проверку на вставленность дискеты сделал. а остальное не могу =/ помогите плизз...
вот, эсли это раздуплишь, вообщем так, на уровне ф-й биоса, ставишь читать то что хочешь, если ошибку выдаёт - то такого сектора, на такой то дорожке и на такой то поверхности нет, или нет дорожки на такой то поверхности, или нету такой поверхности %) вот код из одной фигни, которая ищет читающиеся секторы и их атрибуты запихивает в таблицу: Code (Text): ;данные TABL1290 db 4*1290 dup ("e") ; 3 байта на атрибуты сектора, 1 байт разделитель(резерв) COUN1290 dw 0 ; 2 ПОИСК НА ДИСКЕТЕ 1290 ЧИТАЮЩИХСЯ СЕКТОРОВ MOV AH, 0AH MOV AL, "2" XOR BH, BH MOV CX, 1 INT 10H ; ДИАГНОСТИЧЕСКОЕ СООБЩЕНИЕ - 2 LEA DI, TABL1290 ; УКАЗАТЕЛЬ НА ТАБЛИЦУ (В ТАБЛИЦЕ БУДУТ АТРИБУТЫ 1290 СЕКТОРОВ) ; ПЕРВОНАЧАЛЬНЫЕ ЗНАЧЕНИЯ ДЛЯ Ф-И ЧТЕНИЯ СЕКТОРОВ MOV CL, 2 ; сектор 2,3,4,5.... И ТАК ДЕЛЕЕ (нужно 1290) MOV CH, 0 ; дорожка 0 MOV DH, 0 ; поверхность 0 ; Чтение сектора __ready_start: MOV SI, 3 ; СЧЁТЧИК ПОПЫТОК НА ЧТЕНИЕ __ERR1290S: MOV AH, 2 ; ф-я чтения сектора MOV AL, 1 ; читать 1 сектор MOV DL, 0 ; дисковод А: LEA BX, BUFER512 ; es:bx - bufer INT 13h JNC __READ1290S ; переход если сектор читается DEC SI ; ИНКРЕМЕНТ СЧЁТЧИКА ПОПЫТОК JNZ __ERR1290S ; ПЕРЕХОД - ЕСЛИ СЕКТОР НА ЧИТАЕТСЯ JMP short __max_atr ; ПЕРЕХОД НА СМЕНУ №СЕКТОРА №ТРЕКА №ПОВЕРХНОСТИ __READ1290S: INC COUN1290 ; ИНКРЕМЕНТ СЧЁТЧИКА ЧИТАЮЩИХСЯ СЕКТОРОВ ;Перенесём атрибуты в таблицу tabl1290 MOV [DI], CL ; сектор INC DI MOV [DI], CH ; трек INC DI MOV [DI], DH ; поверхность INC DI MOV byte ptr [DI], "R" ; разделитель (резерв) INC DI ; Проверка максимальных границ и атрибутов секторов __max_atr: CMP COUN1290, 1290 ; найдено 1290 секторов ? JZ __all_1290 ; ПЕРЕХОД ЕСЛИ 1290 ЧИТАЮЩИХСЯ СЕКТОРОВ НАЙДЕНО. CMP CL, 18 ; максимальный сектор? JZ __newt ; ПЕРЕХОД ЕСЛИ МАКСИМАЛЬНЫЙ СЕКТОР НА ТРЕКЕ INC CL ; СЛЕДУЮЩИЙ СЕКТОР JMP __ready_start __newt: ; СЮДА ПЕРЕХОД КОГДА МАКСИМАЛЬНЫЙ СЕКТОР НА ТРЕКЕ CMP CH, 79 ; максимальная дорожка? JZ __newst ; ПЕРЕХОД ЕСЛИ МАКС. ДОРОЖКА НА ПОВЕРХНОСТИ INC CH ; СЛЕДУЮЩАЯ ДОРОЖКА __mutka: MOV CL, 1 ; И минимальный сектор на новой(СЛЕДУЮЩЕЙ) дорожке JMP __ready_start __newst: ; СЮДА ПЕРЕХОДИМ КОГДА НА ПОВЕРХНОСТИ МАКС. ТРЭК CMP DH, 1 ; максимальная сторона? JZ __endready ; ПЕРЕХОД если вторая поверхность читалась, если нет то - INC DH ; поменяем сторону c 0 на 1 XOR CH, CH ; и будем читать с первого сектора нулевой дорожки jmp __mutka ; ПЕРЕХОД НА УСТАНОВКУ МИНИМАЛЬНОГО СЕКТОРА __endready: ; прочитана вся дискета и не найдено 1290 ЧИТАЮЩИХСЯ сектора MOV AH, 9 LEA DX, sec_r_err INT 21H MOV AH, 10H INT 16H JMP __START __all_1290: ; СЮДА ПЕРЕХОД ЕСЛИ НАЙДЕНО 1290 ЧИТАЮЩИХСЯ СЕКТОРА
Слотов на дорожке не бывает, как ни странно. Вот секторы -- бывают Читаешь первый сектор нулевой дорожки (головки) нулевого цилиндра -- т.е. самый-самый первый сектор дискеты вообще. Проще, кстати, это делать не через сервисы ДОС, а через BIOS (функция 02h прерывания INT 13h) -- заодно узнаешь, есть ли дискета (если вернёт ошибку, значит, дискеты либо нет, либо она не читается). Самый первый сектор -- загрузочный (в нём находится программа-загрузчик, которая осуществляет загрузку системы с дискеты). Однако, кроме загрузчика, в нём присутствует так называемый BPB (BIOS Parameters Block -- блок параметров BIOS). В нём содержится информация о дискете, в т.ч. её "геометрия". Так, по смещению 18h от начала загрузочного сектора хранится число секторов на одной дорожке (длиной слово, т.е. два байта), по смещению 1Ah -- число головок (также слово), а в 13h -- общее число секторов на диске (тоже слово). Число цилиндров не хранится, но его можно вычислить, опираясь на эти три поля.
хм...вот я где-т вычитал ну воть кусок кода Code (Text): mov ah,32h mov dx,1 mov a,bx int 21h mov ax,440dh mov bx,1 mov cl,60h mov ch,08h lea dx,a int 21h первая часть кода находит аппаратное устройство вроде а после выполнения второго куска нашли указатель на блок свойств теперь надо это в структуру кинуть... а вот элементы этой структуры я и не помню =/
unforgiven У меня нет функций ДОСа -- я под него не программирую. Потому и опирался на функции БИОСа.
жаль =( а то я так понял можно через досовскую 60h функцию сделать но у меня для неё описания нет =/ а вообще спасибо...завтра отосплюсь, поразбираюсь
Этот BPB сильно ущербный и описать в нём, скажем, "геометрию" xdf не получится. Поэтому когда дискета форматится в xdf никакого BPB туда не пишется. Причём xdf, по-моему, можно прочитать биосом, но только если вручную заказ на каждый сектор оформлять. Кстати стандартный формат 1440K вполне работает везде и без BPB. Проверял.
r90 Знаю, и что с того? Единого стандартного способа узнать геометрию диска нет, не считая тупой попытки прочитать его весь со всеми возможными извратами (менять размеры секторов, искать удалённые секторы и т.д. и т.п.). Но мне очень кажется, что у человека задача опознать обычный МСДОСнутый диск, а там БПБ сработает. Не должен по идее. Во всяком случае, это будет неправильно: параметры диска теоретически могут меняться, и считать их неизменными -- некорректно.
:'( не понимаю....зачем читать сектора, если можно сразу получить кол-во сторон, кол-во дорожек, кол-во секторов на дорожке в 60h вроде хранится...в книге той такого нет =( подскажите
SII можешь поподробнее написать пожайлуста? =/ вот Code (Text): MOV AH, 2 MOV AL, 1 MOV DL, 0 LEA BX, BUFER512 INT 13h ну вот...считал я сектор а как из него инфу вытащить ?
задачи человека я определяю по его посту, а там ничего не сказано про мсдосность. какие параметры? обычно тупо считают что дискета имеет 80 дорожек, две головы, и 18 полукилобайтовых секторов на дорожке. этого предположения вполне достаточно чтобы прочитать формат 1440K, вне зависимости от всех прочих параметров формата, типа inteleave и sector skewing. То есть может быть какие-то тупые биосы этого не делают -- не знаю. Но я с такими не сталкивался. Венда, по-моему, не замечает отсутствия BPB, хотя не уверен. А драйвер флоповода в лине вообще не обращает внимания на BPB -- он просто предоставляет несколько устройств типа fd0u*, которые позволяют сказать этому драйверу какой формат использовать при работе с дискетой: Code (Text): [rgo ~]$ ls /dev/fd0u* /dev/fd0u1040 /dev/fd0u1600 /dev/fd0u1743 /dev/fd0u1920 /dev/fd0u800 /dev/fd0u1120 /dev/fd0u1680 /dev/fd0u1760 /dev/fd0u360 /dev/fd0u820 /dev/fd0u1440 /dev/fd0u1722 /dev/fd0u1840 /dev/fd0u720 /dev/fd0u830 есть ещё /dev/fd0, который пытается автодетектить форматы перебором всех известных ему.
unforgiven смотрим сюда: http://en.wikipedia.org/wiki/BIOS_parameter_block и далее по ссылкам. PS. кстати, обратил внимание на фразу по указанной ссылке: Этот BPB чисто msdos'овая заморока оказывается. Вот наверное поэтому я её и не встречал нигде.
Дорожек может быть не 80, а больше или меньше, секторов -- тоже, головок -- тоже (одна или две), ну а сами секторы могут иметь размер 128, 256, 512 или 1024 байта. Кроме того, контроллер гибких дисков поддерживает "удалённые" секторы, отличающиеся от обычных одним битом в своём заголовке. Кроме того, информация на дискету может писаться либо с использованием частотной модуляции (FM), либо модифицированной частотной модуляции (MFM) -- и всем этим управляет контроллер. Так что теоретически вариантов полно. Нравится или нет, а стандарт де-факто на обмен информацией с помощью дискеты (и флэшки, кстати, тоже) -- это мелкомягкие файловые системы (FAT12 и FAT32). Если отформатировать носитель в другой файловой системе, прочитать его удастся уже не везде. Формально Вы правы, но я подошёл к вопросу с другой стороны. Создание полноценного анализатора геометрии дискеты -- весьма непростая задача, требующая, вероятно, прямого программирования FDC (в силу тех вещей, что я перечислил в начале этого поста), что под силу лишь достаточно квалифицированному программисту. Но ему навряд ли потребовалось бы задавать вопросы на форуме новичков -- он бы скорей выступал здесь в роли эксперта. Значит, мы имеем дело с новичком, но новичок вряд ли возьмётся за написание анализатора геометрии, особенно в наше время, когда "защищённые" с помощью разных махинаций с форматом дискеты практически не встречаются (ну, разве что новичок . Куда вероятнее, что ему просто потребовалась информация о геометрии совершенно стандартной дискеты, ну а стандартом для сего носителя информации, как я уже говорил, является FAT12, а не какая-либо другая система.
Code (Text): .code ... push ds pop es mov ax, 0201h mov cx, 1 xor dx, dx mov bx, offset Buffer int 13h jc ReadError ; Переход, если ошибка чтения mov ax, word ptr Buffer + 18h ; Число секторов на дорожке mov SectorsPerTrack, ax mov bx, word ptr Buffer + 1Ah ; Дорожек в цилиндре (т.е. число головок) mov HeadsPerCylinder, bx mul bx ; dx:ax - число секторов в цилиндре mov bx, ax ; Старшую часть игнорируем - секторов мало... mov ax, word ptr Buffer + 13h ; Число секторов на диске xor dx, dx div bx ; ax - число цилиндров mov Cylinders, ax ... .data Buffer db 512 dup (?) SectorsPerTrack dw ? HeadsPerCylinder dw ? Cylinders dw ? Код не проверялся. Вроде должен работать... Есно, надо написать начало и концовку программы, а также обработку ошибки.
SII пасиб...вот ток про вывод спросить хотел Code (Text): .model small .stack 100h .data Buffer db 512 dup (?) SectorsPerTrack dw ? HeadsPerCylinder dw ? Cylinders dw 0 temp dw 0 msg db 'ERROR$' .code start: mov ax,@data mov ds,ax ;Основноле тело push ds pop es mov ax, 0201h mov cx, 1 xor dx, dx mov bx, offset Buffer int 13h jc error ; Переход, если ошибка чтения jmp ok error: mov ah,09h lea dx,msg int 21h jmp exit ok: mov ax, word ptr Buffer + 18h ; Число секторов на дорожке mov SectorsPerTrack, ax mov bx, word ptr Buffer + 1Ah ; Дорожек в цилиндре (т.е. число головок) mov HeadsPerCylinder, bx mul bx ; dx:ax - число секторов в цилиндре mov bx, ax ; Старшую часть игнорируем - секторов мало... mov ax, word ptr Buffer + 13h ; Число секторов на диске xor dx, dx div bx ; ax - число цилиндров mov Cylinders, ax ;34 call vivod mov ax,SectorsPerTrack call vivod mov ax,HeadsPerCylinder call vivod ;Завершение exit: mov ax,4c00h int 21h vivod proc push ax push dx push bx push cx mov temp,ax mov dl,byte ptr temp mov bl,byte ptr temp + 1 mov bh,bl and bl,11110000b ;сбрасывает 4 последних в нули and bh,00001111b ;4 первых сбрасывает shr bl,4h ;смещает 4 вправо add bl,30h ;разница между числом и аски add bh,30h ;тож самое mov dh,dl and dh,00001111b and dl,11110000b shr dl,4h add dl,30h add dh,30h mov cl,dl mov ah,02h mov dl,bl int 21h mov dl,bh int 21h mov dl,cl int 21h mov dl,dh int 21h mov dl,10d int 21h pop cx pop bx pop dx pop ax ret vivod endp end start end всё пашет, но я вывожу число посимвольно так и надо ? и ещё... Code (Text): mov dl,byte ptr temp вроде один байт, а почему-то берётся две цифры числа...объясните пожайлуста =/
Во-первых, байт -- это всегда две шестнадцатеричные цифры (одна цифра -- 4 бита, а в байте их 8). А во-вторых, вывод какой-то кривой. Думать лень и некогда, но смахивает на неправильный.