ошибка ф-и int 13h

Тема в разделе "WASM.ASSEMBLER", создана пользователем 0136, 29 окт 2008.

  1. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Привет, есть алгоритм, который последовательно записывает сектора дискеты с помощью ф-и int 13h, в виндовс 98 всё работает, а в ХР записывается 81 сектор, при попытки записать 82-ой сектор дискеты происходит ошибка, ошибка..... код ошибки такой - АН=9, перекрытие DMA: попытка записи через 64K-байтовую границу. Кто то с таким сталкивался?
     
  2. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Даю поправку, это не из за ХР, только что вместо ХР загрузил ДОС... тоже самое, проблема возникает на новых пк. На старом пне3 (я понимаю что это и не из за проца) и др пк ниже класса всё работает, а вот стоит два пня4 и на них одинаковый прикол - не работает! Может в биосе нужно какие то настройки выставить или что??
     
  3. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    0136
    А может стоит ошибки поискать в твоем коде. Тоже так было именно эта ошибка, но тогда проблема была в коде. толи регистры не обнулялись толи еще что-то.
     
  4. Ra_Sh

    Ra_Sh New Member

    Публикаций:
    0
    Регистрация:
    23 сен 2008
    Сообщения:
    46
    OffTop
    Pavia в копилку о PC.
    http://avaxhome.ws/ebooks/programming_development/0750697474.html
     
  5. Memphis

    Memphis New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2008
    Сообщения:
    104
    0136
    Кто то с таким сталкивался? - я, когда писал/читал флоп через Int 13/Int 40. И не важно, какая операционка (ДОС/Виндовс) и на какой машине. Код ошибки говорит только об одном - наступает момент, когда Ваши данные попадают на границу сегмента. ДМА контроллер этого не допускает.

    Привет, есть алгоритм, который последовательно записывает сектора дискеты с помощью ф-и int 13h - срочно пересмотреть алгоритм, в нем ошибка. Пройдите запись отладчиком, выясните, какой сектор не пишется, высчитайте, где он лежит в ОЗУ.
     
  6. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Согласен. Автору нужно показать свой алгоритм и мы все вместе определим, в чем причина ошибки. Позволю себе процитировать свой не очень давний пост с форума osdev.org:
     
  7. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Привет, попробуйте у себя пожалуйста (у меня возникает ошибка после записи 81 сектора, там c4et4ik по ds:0000). И ещё раз повторюсь - на старых пк работает, а вот в студии у меня две машины новые, пни4, и биосы у них разные, у одной авард, у второй феникс, и на них вот такая вот ошибочка :)
     
  8. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Нашёл причину, но не могу понять почему??? Ведь на старом пк работает!
    Ошибка возникает при условии если адрес буфер es:bx смещению 0А200h. Чё за дела? именно эти 512 байт не могу записать, они как раз выпадают на 82 сектор.
     
  9. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Короче, диапазон смещения 0А061h - 0А25Fh фиг записывается, если кто знает как этот диапазон записать - скажите пожалуйста. А так всем спасибо!
     
  10. Memphis

    Memphis New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2008
    Сообщения:
    104
    0136
    Ошибка возникает при условии если адрес буфер es:bx - вся соль в том, какое значение принимает сегмент ES. Под ДОСом/Виндозой/одной_машине/другой/сколько_резидентов_загружено - в каждом случае будет свое значение ES. Я загрузил Вашу прогу под отладчиком и вижу - писАть начинают с ОЗУ 16AE:0000 (на моей машине), что эквивалентно адресу 1000:6AE0. Разумееется, никак не получится записать скопом 80h секторов - неминуемо будет нарушена граница сегмента. Поэтому, в Вашей проге нужен дополнительный буфер 512 байт (аналог буферов для ДОСа/Виндовс), который не пересекает границу сегмента. Те сектора, которые отдатут ошибку 9, надо будет копировать в этот буфер и проводить запись с него. Увы, другого пути нет.
     
  11. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    спасибо за подсказку! ок!
     
  12. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    а буфера наверное два нужно сделать, вдруг один из них тоже будет на границе, правильно?
     
  13. Memphis

    Memphis New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2008
    Сообщения:
    104
    0136
    Достаточно одного. Его надо правильно расположить в памяти - при запуске/инсталле проги придется анализировать абсолютное значение ES. Возможно, будет такая ситуация, что придется пропустить N-ное число параграфов памяти (это и будет граница сегмента) для того, чтобы правильно организовать этот буфер. Но гораздо проще работать с детерминированным значением сегмента, к примеру ES=6000/7000/8000.
     
  14. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Если записывать посекторно, то можно записать и 80h секторов, и 180h. Главное, выровнять буфер в памяти на границу 512 байт (конечно здесь я имею в виду линейный адрес, а не смещение в каком-либо сегменте). Если выполнять многосекторную запись, то на дискету в отличии от жесткого диска за раз можно записать только секторы, расположенные в пределах одного трека, т.е. для дискет известного типа максимум 18 секторов и то при условии, что запись будет выполняться, начиная с самого первого сектора трека.

    Я лично писал код для чтения с дискеты (принципиально запись абсолютно ничем не отличается), позволяющий заполнить практически всю базовую память. Т.е. на лицо использование буфера достаточно большого размера. Единственное, что я делал, так это перегружал содержимое сегментного регистра при считывании очередных 64 Кб данных. Работоспособность данного кода проверена на огромном количестве как старых, так и новых компьютеров.
     
  15. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Вот кстати код, при необходимости выполняющий перезагрузку сегментного регистра:
    Код (Text):
    1.   add bh,02h
    2.   jnz @f
    3.   mov dx,es
    4.   add dh,10h
    5.   mov es,dx
    6. @@:
    bl=00h, т.е. смещения кратны 512, как впрочем и базовые адреса сегментов.
     
  16. Memphis

    Memphis New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2008
    Сообщения:
    104
    Phantom_84
    Можно Ваш код и упростить:
    Код (Text):
    1. mov ax,es
    2. add ax,20h
    3. mov es,ax
     
  17. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    О, это идея. По виду и по объему он действительно стал проще/меньше. Просто я привык выполнять перезагрузку сегментных регистров как можно реже.
     
  18. Memphis

    Memphis New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2008
    Сообщения:
    104
    Phantom_84
    Просто я привык выполнять перезагрузку сегментных регистров как можно реже. - и я не любитель сегменты перезагружать. Но иногда красивше получается, да и от количества зависит - 100 раз, это одно. А вот 100000 раз - другое.