Профессиональный цифровой диммер и пульт DMX512
Программа управления световыми приборами DMX512
Фонтаны, визуализация Изготовление фонтанов и оборудования


О протоколе ATAPI-CD

 

     
 

   Данный документ никоим образом не является полным описанием стандартного   ATAPI-CD. Здесь были собраны только основные данные, необходимые для общего   понимания принципов функционирования. Предполагается знание (хотя бы в   общих чертах) IDE-интерфейса (стандарт ходил под именем ATA-R4C.*).
        Для желающих быстро заполучить исходники для управления CD-ROM могу   порекомендовать драйвер VIDE-CDD.SYS. Он проще всего поддается   дизассемблированию и содержит достаточно неплохой код. Кроме того,   в исходных текстах драйвера CD для Linux содержится много полезной   информации, хотя ориентация на "юниксоидный" тип запросов мешает   использованию этих текстов для компиляции под MS-DOS.


                     Соглашения и используемые сокращения.

    При указании конкретных адресов подразумевается, что CD является    мастером, адрес контроллера - 170h. Если у Вас используются другие адреса,    вместо 17x необходимо подставить 1Fx, 1E8+x или 168+x.

    Тик = 18.2 герца.

    Данные  длиной в слово или двойное слово в/из CD идут в формате
    co старшим первым байтом ( в отличие от PC, где первый байт - младший).

    AP - Atapi пакет, 12 байт передаваемых в CD-Rom. Содержат команду
         и основные данные для нее. ВНИМАНИЕ: возможно существуют устройства
         c пакетом длиной в 16 байт. Однако, подавляющее большинство
         драйверов не анализируют и не поддерживают такой формат.
         Для определения размера пакета используется ATA-команда A1h.

    AK - Atapi команда
    M  - минуты
    S  - секунды
    F  - номер фрейма (1/75 секунды)

    Часто используемые биты региста cостояния (177h):
        BSY - бит 80h
        DRQ - бит 08h
        CHK - бит 01h


                      I. Определение наличия CD в системе

        Для проверки присутствия Atapi-CD устройства необходимо:

        1. На нужном шлейфе выбрать требуемое устройство (Master/Slave) в
           регистре 176h.
        2. Проверить отсутствие BSY
        3. Если занято - устройства нет.

        Далее можно дать команду общего сброса (вывести код 8 в регистр 177h
        и подождать 1-3 тика), либо попробовать обойтись без этого. Если
        CD находится в cостоянии нормального ожидания команды, сброс давать
        не обязательно.

        3. В порты 174h и 175h записать нечто, отличающееся от 14EBh.
        4. В порт 177h вывести команду ECh и подождать пару тиков.
        5. Проверить порт 174h (д.б. = 14h) и порт 175h (д.б. = EBh).
           При этом надо учитывать, что в регистрах должна будет
           установлена ошибка (177h - 51h, 171h - 04h). Это нормально.

        Если все условия соблюдены, то можно считать, что на IDE-шлейфе
        присутствует Atapi устройство. Для уточнения типа устройства можно
        воспользоваться уже Atapi-командами.

        Данный алгоритм может применяться только тогда, когда достоверно
        известно, что CD до этого не выполнял команд. В противном случае
        бит BSY может быть установлен. Если необходнимо, проверку регистра
        состояния можно смягчить, проверяя только наличие самого ATA
        устройства записью в регистры.


                     II. Выполнение команд

        Для выполнения AK необходимо (работа без прерываний):
        1. Выбрать соответствующее устройство (Master/Slave) в порту 176h
        2. Дождаться готовности (BSY и DRQ = 0). Драйверы ждут до 10-20
           секунд. Если готовности нет - можно попытаться сбросить привод.
        3. Установить желательный размер блока в регистрах 174h (мл.)
           и 175h (ст. часть) Если команда не возвращает данные, это можно
           и не делать. Для DMA-шных обменов в этот момент надо установить
           и другие регистры.
        4. В 177h записать команду A0h. В ответ на это устройство может
           установить BSY на время подготовки к приему AP.
        5. Дождаться требования данных (DRQ=1 и BSY=0). (обычно ждать не
           надо - драйв выставляет требование сразу). При этом в регистре
           172h два младших бита должны иметь значение 01.
        6. В режиме словной пересылки записать в порт 170h 6 слов AP.
        7. Дождаться готовности (BSY=0). (В зависимости от типа команды и
           других обстоятельств, драйв может выполнять команду за время от
           тысячных долей секунды до десятков секунд (Если, например, плохо
           читается сектор диска).
        8. Проверить бит DRQ и если он установлен, то считать из регистров
           174h и 175h длину передаваемого блока.
        9. Если длина =0 или бит DRQh в 177h не установлен - п. 11,
            иначе произвести обмен данными через порт 170h. При этом два
            младших бита регистра 172h могут принимать значение 00 (при
            передаче данных в CD) или 02 (при приеме данных из CD).
        10.Если команда не закончила обмен (бит BSY=1), то повторить с п 7.
        11.После завершения команды два младших бита регистра 172 обычно
           принимают значение 03, что означает готовность драйва к выдаче
           статуса завершения команды. При этом можно проанализировать
           результат завершения команды (регистры 177h и 171h). При ошибках
           можно использовать ATAPI-функцию 03h для получения более детальной
           информации.



                     III. Типы команд

        По режимам обмена команды можно разделить на три группы:
        а) Управления
                Как правило, все данные находятся в AP. В некоторых командах
                применяется дополнительно пересылаемый блок данных.
                Результат можно определить по регистрам ошибок (171h и 177h)
                или с помощью дополнительной команды получения состояния.
        б) Передачи данных
                Адресные данные и параметры передачи находятся в AP
                Поскольку пишущие CD не рассматриваются (мне они не известны),
                то блок данных, передаваемых в CD, отсутствует.
                Если в команде подразумевается передача данных из CD и
                нет ошибок, CD драйв выдает в ответ на команду блок (блоки)
                данных.
        в) Получения информации
                Все данные о запросе находятся в AP. В ответ на команду СD
                выдает блок данных.



                        IV. ATA команды

        У CD есть несколько вспомогательных команд, которые исполняются
        так же, как и команды обычного IDE-винчестера. При этом назначение
        регистров совпадает с назначением по ATA.

        Вот основные команды:

        A0h - Команда передачи AP.

        A1h - Идентификация привода. Аналог команды ECh для IDE-винчестера,
              но формат выходного блока другой (описан в приложении C).

        ECh - Воспринимается как ошибка, но в регистрах 174h и 175h
              устанавливается сигнатура 14EBh - признак Atapi устройства.

        08h - Програмный сброс. Выполняет процедуру начальной инициализации.

        Также, могут выполняться некоторые команды управления сохранением
        энергии, установки возможностей и пр. Во многих приводах они
        воспринимаются как правильные команды, но реально не исполняются или
        исполняются частично.



                V. Команды в ATAPI-пакетах

Первый байт в AP является кодом команды. Это единственный байт, который
анализируется всегда. Остальные 11 байт содержат информацию, зависящую
от конкретной команды.

----------------------------------------------------------------------
Команда 00h - пустышка, проверяет готовность

Пакет:
        db  0
        db  11*dup(0)   ; *

        Ничего не делает, может применяться для проверки смены диска

        ПРИМЕЧАНИЯ:
        1) Первая команда после смены диска будет отвергнута с кодом ошибки
           "смена носителя".
        2) Здесь и далее: данные помеченые "*", как правило, не анализируются
           CD, но для совместимости должны быть установлены в 0.

------------------------------------------------------------------------
Команда 01h - Установить головку на начало диска

Пакет:
        db 01h
        db 12*dup(0)    ; *
        Команда управляющая (практически не используется).

----------------------------------------------------------------------
Команда 03h - читать состояние привода

Пакет:
        db 03h
        db 3*dup(0)     ; *
        db Len          ; длина выходного блока
        db 7*dup(0)     ; *

        На выходе таблица из 12h байт, в которой самыми интересными являются
        байты 2, 0С и 0D - это три байта кода ошибки последней операции.

--------------------------------------------------------------------------
Команда 012h - читать строку параметров изготовителя драйва

Пакет:
        db 12h
        db 0h,0h        ; иногда здесь устанавливаются некие параметры
        db 0h           ; *
        db Len          ; длина выходной строки
        db 7*dup(0)     ; *

        Драйв выдает некую строку изготовителя (в формате изготовителя)
        Зависит от типа CD-Rom. Иногда применяется в драйверах для проверки
        соответствия драйвера и устройства.

        Структура выходного блока:
        0       db      1Fh     - тип устройства (CD = 5)
                        E0h     - для CD =0
        1       db      7Fh     - = 0 (для совм. со SCSI-1)
                        80h     - поддерживаются сменные носители
        2       db      0       - версии ISO, ECMA и ANSI.
        3       db      0       - для совместимости со SCSI-2
        4       db      ?       - длина оставшегося блока
        5       db   2 dup(?)   - резервные
        7       db      0       - для совместимости со SCSI-2
        8       db   8 dup(?)   - строка изготовителя (там бывает 'ATAPI')
        10h     db 10h dup(?)   - название продукции
        20h     db 4   dup(?)   - ревизия

        Текстовые поля образуют одну строку, разделенную пробелами.

---------------------------------------------------------------------------
Команда 01Bh - управление треем и прочее

Пакет:
        db 1Bh
        db 3*dup(0)     ; *
        db Func         ; подфункция
        db 7*dup(0)     ; *

        Команда управляющая.

        Подфункции:
        0 - войти в режим Sleep
        1 - остановить проигрывание/чтение
        2 - выдвинуть трей
        3 - закрыть трей

---------------------------------------------------------------------------
Команда 01Eh - блокировка трея

Пакет:
        db 1Eh
        db 3*dup(?)     ; *
        db Func         ; подфункция
        db 7*dup(?)     ; *

        Команда управляющая.

        Младший бит Func= 0 - разблокировать трей
                        = 1 - заблокировать трей

---------------------------------------------------------------------------
Команда 025h - получить размер вставленного диска в секторах.

Пакет:
        db 25h
        db 11*dup(0)    ; *

        Команда информационная.

        Пользователю в ответ передается блок из 8 байт:
        dd Sectors      ; число секторов на текущем диске
        dd SectSize     ; размер сектора (как правило, не зависит
                        ; от диска и равен 930h)
---------------------------------------------------------------------------
Команда 02Bh - Seek

Пакет:
        db 2Bh
        db 2*dup(0)     ; *
        db M,S,F        ; куда позиционироваться
        db 6*dup(0)     ; *

        Команда управляющая.
----------------------------------------------------------------------------
Команда 042h - смешанная информация (чтение субканала)

Пакет:
        db      42h
        db      ScMsf   ; 0/2 - тип выдачи адресов (номер сектора или MSF)
        db      FullInfo; вариант запроса (полный/краткий - бит 40h)
        db      Func    ; подфункция (только для полного запроса)
        db      3*dup(0); *
        dw      Length  ; Длина таблицы
        db      3*dup(0); *

        Команда информационная, выдает блок следующей информации:

        00h dw   состояние проигрывания аудио:
                      00h - неизвестно или не поддерживается
                      11h - Играет аудио
                      12h - Аудио стоит
                      13h - Аудио остановилось на конце
                      14h - Открыта дверь или ошибка запуска
                      15h - Прочее
        02h dw  длина последующих данных (0 - нет)

        04h и далее  присутствует при наличии бита 40h в FullInfo и
              зависят от Func

              Func не равен 2 или 3
              04h db  01h       (формат данных субканала = 1)
              05h db  Ctrl/Addr
              06h db  TrackNumber
              07h db  Point or Index
              08h db  0
              09h db  3*dup(?) - MSF/SECTOR на диске
              0Ch db  0
              0Dh db  3*dup(?) - MSF/SECTOR на дорожке

               --Подфункция 2-- (Получить UPC код)
              04h db  02h       (формат данных субканала = 2)
              05h db  3h*dup(?)
              08h db  80h        - флажок наличия UPC (если нет, то UPC отсутствует)
              09h db  0Ch*dup(?) - здесь хранится UPC код (6 цифр в BCD коде)
              15h db  3*dup(?)   - Положение чего-то на диске в формате MSF

               --Подфункция 3-- (получить ISRC код)
              04h db  03h       (формат данных субканала = 2)
              05h db  Ctrl/Addr
              06h db  TrackNumber  - не всегда используется.
              07h db  ?
              08h db  80h - флажок присутствия (аналогично функции 02h)
              09h db  далее запись ISRC

-----------------------------------------------------------------------------
Команда 043h - информация о дорожках (READ TOC)

Пакет:
        db      43h
        db      ScMsf   ; 0/2 - тип выдачи адресов (номер сектора или MSF)
        db      4*dup(0); *
        db      BegTrk  ; начальная дорожка (от 1, 0 заменяется на 1)
        dw      Length  ; Длина таблицы
        db      Func    ; варианты выдачи информации (0/40h/80h)
        db      2*dup(0); *

        Команда информационная, выдает таблицу дорожек. Максимальная длина
                таблицы 8*64h+4 байт или 64h (100.) дорожек.

        Func    = 00h   ; получить обычную таблицу дорожек
                = 40h   ; получить таблицу сессий
                = 80h   ; получить обычную таблицу в расширенном формате

        Общий формат таблицы :
        dw      Len             ; длина последующих полей в байтах
        db      BegTrk          ; первая дорожка
        db      EndTrk          ; последняя дорожка
        d?      <track_Def>     ; описание дорожек

        Описание дорожек м.б. трех форматов:

        1) 5 байт на дорожку (внутренний формат, наружу из CD не выдается):
                db      Ctrl/Addr       ; тип дорожки и флаги
                db      Index           ; индекс дорожки (номер)
                db*3    Start           ; адрес начала дорожки

        2) 8 байт на дорожку (Func=0h/40h):
                db      ?
                db      Ctrl/Addr       ; тип дорожки и флаги
                db      TrackNumber     ; номер дорожки
                db      ?
                db*4    Start           ; адрес начала дорожки

        3) 11 байт на дорожку (Func = 80h):
                db      Res1
                db      Ctrl/Addr       ; тип дорожки
                db      Res2
                db      Index           ; индекс дорожки
                db      Res3
                db      Res4
                db      Res5
                db*4    Start           ; адрес начала дорожки

        Ctrl/Addr  - тип дорожки(то-же, что и в MSCDEX, но переставлены
                     тетрады):

                Ctrl (младшая тетрада, отдельные биты):

                01 - есть pre-emphasis
                02 - разрешено копирование
                04 - дорожка данных
                08 - 4 канала (а не 2)

                Addr (старшая тетрада, коды):
                0 - нет субканала
                1 - в субканале закодирована позиция
                2 - в субканале закодирован UPC
                3 - в субканале закодирован ISRC
                прочее - зарезервировано

                Самые распространенные коды:
                14h - ROM
                10h - audio

        Index - кодируется в BCD и для обычной дорожки находится в интервале
        01-99. Коды A0 и выше имеют специальное значение, они не соответстуют
        физическим дорожкам на диске, а носят служебный характер -
        информируют о числе дорожек, начале диска, конце диска и т.п.

        Start - в зависимости от запроса, может быть либо номером сектора,
        либо адресом сектора в формате MSF.

-----------------------------------------------------------------------------
Команда 044h - информация о реальных метках положения (Read HEADER)

Пакет:
        db      44h
        db      SL      ; бит 2 - что записывать в выходной буфер
                        ; (исходный номер сектора или считанный)
        db      0       ; *
        db      M,S,F   ; Номер сектора
        db      0       ; *
        dw      Len     ; длина выдаваемой информации
        db      3*dup(0); *

        Команда информационная, выдает следующую таблицу из 8 байт:

        db      SectorType      ; тип формата сектора (data mode)
        db      4*dup(0)
        db      M,S,F           ; адрес сектора

        Пакет выдается только в том случае, если CD смог считать заданный
        сектор и определить его тип.
-----------------------------------------------------------------------------
Команда 045h - проигрывать audio в терминах блоков (длина - слово)

Пакет:
        db 45h
        db 0            ; *
        dd StartBlock   ; блок начала проигрывания (-1 - с тек. положения)
        db ?
        dw Length       ; число блоков
        db 3*dup(?)     ; *
        Команда управляющая.
-----------------------------------------------------------------------------
Команда 047h - проигрывать audio в стиле MSF

Пакет:
        db 47h
        db 2*dup(?)     ; *
        db M,S,F        ; начало отрезка (FF:FF:FF - текущая позиция)
        db M,S,F        ; конец отрезка
        db 3*dup(?)     ; *
        Команда управляющая.
-----------------------------------------------------------------------------
Команда 04Bh - Start/stop audio

Пакет :
        db  4Bh
        db  7*dup(0)    ; *
        db  Func
        db  3*dup(0)    ; *

        Команда управляющая.

        Младший бит Func= 0 - остановить
                        = 1 - запустить
---------------------------------------------------------------------------
Команда 04Eh - остановить проигрывание

Пакет:
        db 4eh
        db 11*dup(?)    ; *
        Команда управляющая.
----------------------------------------------------------------------------
Команда 055h - установить  параметры

Пакет:
        db      55h
        db      ?       ; бит 1 - сохранять в NVRAM (?)
        db      Page    ; требуемая страница параметров
        db      4 dup (?)
        dw      Length  ; длина таблицы
        db      3*dup(0); *

        Команда управляющая, коды и формат страниц описан в команде 5Ah.

----------------------------------------------------------------------------
Команда 05Ah - получить  параметры

Пакет:
        db      5Ah
        db      ?
        db      Page  - определяет требуемые параметры, состоит из двух
                        битовых полей:

                        3Fh - номер требуемой страницы параметров:
                                01h - параметры исправления ошибок
                                0Dh - общие параметры
                                0Eh - аудио-управление
                                2Ah - параметры устройства (только читается)
                                3Fh - все странички

                        C0 - биты типа требуемой страницы:
                                00 - текущие значения
                                01 - измененные значения
                                10 - значения по умолчанию
                                11 - сохраненные значения

        db      4 dup (?)
        dw      Length  ; длина таблицы
        db      3*dup(0); *

        Команда информационная, выдает cоответствующую страничку параметров.

        Общий заголовок:
        00h     dw              Длина всего блока (без первого слова)
        02h     db              Состояние привода
        03h     db 5 dup(?);

        Заголовок каждой страницы:
        08h     db      Номер страницы из запроса
        09h     db      Длина страницы

        Страница 01 - исправление ошибок
        0Ah     db      Параметр исправления ошибок
        0Bh     db      Счетчик повторов чтения

        Страница 0D - общие параметры
        0Ah     db      ?
        0Bh     db      Множитель таймера неактивности
        0Ch     dw      Число S единиц в M единице для формата MSF (60)
        0Eh     dw      Число F единиц в S единице для формата MSF (75)

        Страница 0E - аудио параметры
        0Ah     db      ?       параметр не исп., но изменяется
        0Bh     db      2 dup(?)
        0Dh     db      ?    =0 LBA всегда равен номеру сектора,
                                старший бит указывает правильность следующего
                                поля
        0Eh     dw      0       Число логических блоков в секунду для
                                проигрывания. (как-правило не используется)
        10h     db      мл. тетрада - биты выходного порта канала 0
        11h     db      громкость канала 0
        12h     db      мл. тетрада - биты выходного порта канала 1
        13h     db      громкость канала 1
        14h     db      мл. тетрада - биты выходного порта канала 2
        15h     db      громкость канала 2
        16h     db      мл. тетрада - биты выходного порта канала 3
        17h     db      громкость канала 3

        Страница 2Ah - параметры устройства (только чтение)
        ; биты присутствия/отсутствия функций
        0Ch     db      01h - проигрывание аудио
                        02h - композитный аудио/видео поток
                        04h - Digital out to port 1
                        08h - Digital out to port 2
                        10h - чтение секторов Mode 2 Form 1
                        20h - -----//-------- Mode 2 Form 2
                        40h - Чтение многосессионных дисков
                        80h - ?
        0Dh     db      01h - Чтение RedBook через команду Read-CD
                        02h - Чтение RedBook  "with accurate stream"
                        04h - Чтение субканала
                        08h - Поддержка деинтерливинга данных субканала
                        10h - Поддержка "C2 error pointers"
                        20h - Поддержка чтения ISRC
                        40h - Поддержка чтения UPC
                        80h - ?
        0Eh             01h - блокировка носителя
                        02h - чтение статуса блокировки
                        04h - Disk prevent jumper present
                        08h - команда выброса носителя
                        10h - ?
                        E0h - Тип загрузчика:
                                  0 - Caddy
                                  1 - Tray
                                  2 - Pop-Up
                                  3 - Reserved
                                  4 - Ченджер с индивидуально
                                      меняемыми дисками
                                  5 - Картридж
                                  6 - Reserved
                                  7 - Reserved
        0Fh     db      01h - Раздельная регулировка каналов
                        02h - Раздельный комутатор каналов
                        04h - Информация о наличии диска
                        08h -
                        10h -
                        20h -
                        40h -
                        80h -
        10h     dw      Максимальная скорость обмена в килобайтах
        13h     db      Число градаций регулировки громкости
        14h     dw      Размер буфера в килобайтах
        16h     dw      Текущая скорость обмена
        ;---------иногда может отсутствовать-------------
        18h     db      ?
        19h     db      01h - Digital out по фронту/спаду сигнала BCKF
                        02h - LRCK индицирует левый/правый канал
                        04h - данные в формате LSB/MSB
                        08h
                        10h \  BCKs:     0 - 32
                        20h  |           1 - 16
                        40h /            2 - 24
                                         3 - 24 (I^2S)
                        80h - ?

         Длина каждой из стрниц может быть разной. Здесь описаны только те
         поля, которые более-менее стандартны. Если запрашиваются все
         странички (код 3Fh), то в выходном блоке будет присутствовать один
         общий заголовок и последовательно расположенные странички со
         своими заголовками.

-----------------------------------------------------------------------------
Команда 0A5h - проигрывать audio в терминах блоков

Пакет:
        db A5h
        db 0            ; *
        dd StartBlock   ; блок начала проигрывания (-1 - с тек. положения)
        dd Length       ; число блоков
        db 2*dup(?)     ; *
        Команда управляющая.
---------------------------------------------------------------------------
Команда 0B9h - читать данные

Пакет:
        db B9h  ;
        db Fmt  ; может быть = 00h годится любой формат
                ;              08h обычный CD-диск (Желтая книга)
                ;              10h\  разновидности
                ;              14h/      Green XA
        db 0    ; *
        db M,S,F; начало чтения
        db M,S,F; конец чтения
        db Flg  ; флаги читаемого куска сектора:
                ; 01h   три
                ; 02h     неиспользуемых (?)
                ; 04h           бита
                ; 08h  EDC/Zero/ECC
                ; 10h  основное тело сектора (data)
                ; 20h  описатель адреса сектора (head)
                ; 40h  данные субканала (sub)
                ; 80h  начальные синхробайты (sync)
                ; передаются только те  части секторов, для которых
                ; установлены биты. Передаваемые части сектора должны идти
                ; подряд, без пропусков.
        db 0    ; всегда д.б. =0, иначе ошибка (?)
        db 0    ; *

        Команда передачи данные.
        Если начало=конец, производится позиционирование на указанную
        позицию и тест читабельности. В этом случае данные не передаются.

--------------------------------------------------------------------------
Команда 0BEh - читать данные в терминах секторов
Пакет:
        db BEh  ;
        db Fmt  ;
        dd Sec  ; начало чтения (исп. только 24 бита)
        db 0    ; *
dw ScNum; Число секторов
        db Flg  ; флаги читаемого куска сектора (как в B9h)
        db 0    ; всегда д.б. =0, иначе ошибка (?)
        db 0    ; *

        Команда полностью аналогична команде B9, за исключением задания
        адресов области чтения в терминах секторов.



══════════════════════════════════════════════════════════════════════════════
                             Приложение A
                        Коды ошибок ATAPI устройства
               (взяты из драйвера CD в Linux'е)

┌──────────────────────┐
│  Первый байт         │
├───┬──────────────────┤
│00h│No sense data     │
│01h│Recovered error   │
│02h│Not ready         │
│03h│Medium error      │
│04h│Hardware error    │
│05h│Illegal request   │
│06h│Unit attention    │
│07h│Data protect      │
│08h│(reserved)        │
│09h│(reserved)        │
│0ah│(reserved)        │
│0bh│Aborted command   │
│0ch│(reserved)        │
│0dh│(reserved)        │
│0eh│Miscompare        │
│0fh│(reserved)        │
└───┴──────────────────┘

 Второй и третий байты

 0000h No additional sense information
 0011h Audio play operation in progress
 0012h Audio play operation paused
 0013h Audio play operation successfully completed
 0014h Audio play operation stopped due to error
 0015h No current audio status to return
 0200h No seek complete
 0400h Logical unit not ready - cause not reportable
 0401h Logical unit not ready - in progress (sic) of becoming ready
 0402h Logical unit not ready - initializing command required
 0403h Logical unit not ready - manual intervention required
 0600h No reference position found
 0900h Track following error
 0901h Tracking servo failure
 0902h Focus servo failure
 0903h Spindle servo failure
 1100h Unrecovered read error
 1106h CIRC unrecovered error
 1500h Random positioning error
 1501h Mechanical positioning error
 1502h Positioning error detected by read of medium
 1700h Recovered data with no error correction applied
 1701h Recovered data with retries
 1702h Recovered data with positive head offset
 1703h Recovered data with negative head offset
 1704h Recovered data with retries and/or CIRC applied
 1705h Recovered data using previous sector ID
 1800h Recovered data with error correction applied
 1801h Recovered data with error correction and retries applied
 1802h Recovered data - the data was auto-reallocated
 1803h Recovered data with CIRC
 1804h Recovered data with L-EC
 1805h Recovered data - recommend reassignment
 1806h Recovered data - recommend rewrite
 1a00h Parameter list length error
 2000h Invalid command operation code
 2100h Logical block address out of range
 2400h Invalid field in command packet
 2600h Invalid field in parameter list
 2601h Parameter not supported
 2602h Parameter value invalid
 2603h Threshold parameters not supported
 2800h Not ready to ready transition, medium may have changed
 2900h Power on, reset or bus device reset occurred
 2a00h Parameters changed
 2a01h Mode parameters changed
 3000h Incompatible medium installed
 3001h Cannot read medium - unknown format
 3002h Cannot read medium - incompatible format
 3700h Rounded parameter
 3900h Saving parameters not supported
 3a00h Medium not present
 3f00h ATAPI CD-ROM drive operating conditions have changed
 3f01h Microcode has been changed
 3f02h Changed operating definition
 3f03h Inquiry data has changed
 4000h Diagnostic failure on component (ASCQ)
 4400h Internal ATAPI CD-ROM drive failure
 4e00h Overlapped commands attempted
 5300h Media load or eject failed
 5302h Medium removal prevented
 5700h Unable to recover table of contents
 5a00h Operator request or state change input (unspecified)
 5a01h Operator medium removal request
 5b00h Threshold condition met
 5c00h Status change
 6300h End of user area encountered on this track
 6400h Illegal mode for this track
 bf00h Loss of streaming

-------------------------------------------------------------------------

                        Приложение B
                  Некоторые форматы секторов

┌───────────────────────────────┬───────────────────────────────────────┐
│ Аудио диск (красная книга):   │          audio_sample_bytes           │
│                               │                  2352                 │
├───────────────────────────────┼──────┬──────┬──────┬─────┬──────┬─────┤
│ Данные (желтая, mode 1):      │ sync │ head │ data │ EDC │ zero │ ECC │
│                               │  12  │   4  │ 2048 │  4  │   8  │ 276 │
├───────────────────────────────┼──────┼──────┼──────┴─────┴──────┴─────┤
│ Данные (желтая, mode2):       │ sync │ head │         data            │
│                               │  12  │   4  │         2336            │
├───────────────────────────────┼──────┼──────┼──────┬──────┬─────┬─────┤
│ XA данные (зеленая,           │ sync │ head │ sub  │ data │ EDC │ ECC │
│                 mode2 form1): │  12  │   4  │  8   │ 2048 │  4  │ 276 │
├───────────────────────────────┼──────┼──────┼──────┼──────┴─────┼─────┤
│ XA данные (зеленая,           │ sync │ head │ sub  │ data       │ EDC │
│                 mode2 form2): │  12  │   4  │  8   │ 2324       │  4  │
└───────────────────────────────┴──────┴──────┴──────┴────────────┴─────┘

-------------------------------------------------------------------------

                        Приложение C
           Блок, передаваемый по ATA-команде A1

Смещение
00h     db   битовое поле:
                03h - Длина пакета:   00 - 12 байт
                                      01 - 16 байт
                                      прочее - Reserved
                1Ch - ?
                60h - CMD DRQ Type:   00 - Микропроцессор
                                      01 - Interrupt
                                      02 - Accelerated
                                      03 - Reserved
                80h - Съемное

01h     db      1Fh - Тип устройства: 05 - CD-ROM
                                     (остальные типы можно посмотреть
                                      в описании SCSI)
;--тут пропуск---

14h     dw*0Ah  Серийный номер
28h     dw*3    Что-то от производителя
2Eh     dw*4    Версия прошивки
36h     dw*14h  Название модели
5Eh     dw      Что-то от производителя
60h     dw      0
62h     db      ????? (0)
63h     db      01h - поддержка DMA
                02h - поддержка LBA
                04h - устройство может запрещать использование IORDY
                08h - поддержка IORDY
                20h - поддержка перекрывающихся операций
                40h - поддержка Proxy Interrupt
                80h - поддержка Interleave DMA
66h db PIO time (ns)
67h db PIO mode
69h     db      S/W DMA mode
6Ah     db      1 - Поля 6Сh-73h используются
                2 - Advanced PIO Support (поля 80h-8Dh используются)

; поля 6Ch - 78h взяты из Interrupt List'а. В большинстве CD не используются
6Ch     dw      ??? logical cylinders in current translation mode
6Eh     dw      ??? logical heads in current translation mode
70h     dw      ??? logical sectors per track in current translation mode
72h     dw*2    ??? current capacity in sectors
76h     dw      ??? multiple-sector count for read/write multiple command
78h     dw*2    ??? total number of user-addressable sectors (LBA mode)

;параметры DMA
7Ch     db      S/W DMA modes: 1 - 0; 2 - 0,1; 4 -0,1,2; Прочее - нет DMA
7Dh     db      Текущий режим S/W DMA: 1 - 0, 2 - 1, 4 - 2, прочее - не DMA
7Eh     db      M/W DMA modes (как в S/W DMA)
7Fh     db      Текущий режим M/W DMA
80h db Advanced PIO modes: 4 - PIO 5
2 - PIO 4
1 - PIO 3
82h     dw      Минимальное   время передачи в M/W DMA
84h dw Рекомендуемое ---//----//---
86h     dw      Минимальное   время передачи в PIO без F/C
88h     dw      -----//------//-------//----//---  с F/C (IORDY)
8Ah     dw*2    зарезервировано для будущих  PIO-режимов

; эти два поля используются для определениея параметров
; перекрывающегося обмена
8Eh     dw      типичное время отпускания шины после команды (ms)
90h     dw      ----//-----//-----//-----//----//--- обслуживания (ms)
;
92h     dw      Какой-то номер версии
96h     dw*38h  0
100h    dw*20h  Что-то от производителя
140h    dw*60h  0

-----------------------------------------------------------------------

                               Приложение D
                      Назначение регистров интерфейса

        170h -  Регистр данных. Через этот регистр CD обменивается с
                внешним миром данными. Ввод/вывод только словами.

        171h -  Чтение - регистр ошибок:
                01h - Ошибочная длина
                02h - Обнаружен конец носителя
                04h - Команда отвергнута (бит совпадает по смыслу с ATA)
                08h - Обнаружена смена носителя
                F0h - Младшие 4 бита первого байта кодов ошибки
       
                Запись - регистр доп. возможностей (опциональный):
                01h - включение обмена по DMA
                02h - включение перекрывающихся операций
                FDh - зарезервировано

        172h -  Регистр уточнения причины прерывания:
                01h - Тип передачи:  0 - передача данных, 1 - передача AP
                02h - направление передачи: 0  - в CD, 1 - из CD
                04h - индицирует освобождение шины ATA. (как правило = 0)
                F8h - Зарезервировано
                Сочетания битов 1 и 2 имеют следующий смысл:
                        0 - Ввод блока данных (в CD)
                        1 - Ввод Atapi-пакета
                        2 - Вывод блока данных (из CD)
                        3 - Выдача состояния завершения команды

        173h -  Зарезервирован

        174h - \Регистры длины пересылки. При записи устанавливается
        175h - /желательный размер блока пересылки в байтах. При чтении
                возвращается объем, подготовленный для передачи из CD или
                требуемый для передачи в CD в следующем цикле обмена.

        176h -  Регистр выбора устройства
                0Fh - Зарезервированы (SAM LUN)
                10h - Мастер (0)/ Слэйв (1)
                20h - 1
                40h - Зарезервировано (0)
                80h - 1

        177h -  Регистр команды (запись) / состояния (чтение)
                Биты регистра состояния:
                01h - Ошибка выполнения команды
                02h - Не используется
                04h - Обнаружена скорректированная ошибка чтения
                        (в большинстве устройств постоянно сброшен)
                08h - Устройство требует обмена данными
                10h - Устройство запросило прерывание для обслуживания
                        (во многих приводах установлен постоянно)
                20h - Усторойство готово к DMA-обмену или
                        индикация ошибок (зависит от режима и зачастую не
                        используется)
                40h - Устройство закончило выполнение команды
                        (этот бит лучше не использовать)
                80h - Устройство занято.

        376h -  Регистр управления устройством (мне кажется, он есть не на
                всех устройствах)
                По записи:
                01h - 0
                02h - Запрет прерываний от устройства
                04h - Програмный сброс
                08h - 1
                F0h - зарезервировано

         Примечание: При выполнении обычных ATA (не ATAPI) команд назначение
         регистров совпадает с их назначением по ATA.

-----------------------------------------------------------------------

                               Приложение E
/*****************************************************************/
/* Пример использования ATAPI-CD команд для проигрывания дисков  */
/* без использования драйвера  */
/* Приложение к документации по ATAPI-CD  */
/* Компилятор: BC 3.1, large model  */
/* Это _крайне_ сырая версия. Т.к. большинство приводов расчитаны*/
/* на работу по прерываниям, существуют определенные проблемы при*/
/* работе без них. Информация о проблемах, возникших с различными*/
/* приводами будет очень ценна для создания версии,              */
/* работоспособной на как можно большем количестве устройств.  */
/*****************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>


typedef unsigned char  byte;
typedef unsigned int   word;
typedef unsigned long dword;


/* описатель IDE-устройства */
typedef struct{
int port; /* базовый порт */
char irq; /* номер IRQ 1-15, если отсутствует - 0 */
char ms; /* 1 - мастер, 0 - слэйв */
}ATAPos;


/* Если используются другие прерывания
таблицу надо модифицировать */
static ATAPos Atp[]={
{0x1F0,14,1},
{0x1F0,14,0},
{0x170,15,1},
{0x170,15,0},
{0x1E0,10,1},
{0x1E0,10,0},
{0x168,11,1},
{0x168,11,0},
{0,0,0}};

/* то, что последний раз считалось из 1x7 */
static byte Last1X7=0;

/*static ATAPos *GetDescr(int drvnum){return(Atp+drvnum);}*/

void StoreLBAToMSF(long lba, void *msf)
{
byte *msfb=msf;
lba+=150;
*msfb++=lba/(60L*75L);
lba%=(60L*75l);
*msfb++=lba/75L;
*msfb++=lba%75L;
}


word  GetMSBWord(word cd){return(
(cd >> 8)|
(cd << 8));}

dword GetMSBDword(dword cd){return(
((cd >> 24)&0x000000FFL)|
((cd >>  8)&0x0000FF00L)|
((cd <<  8)&0x00FF0000L)|
((cd << 24)&0xFF000000L));}

/* ждать установки бит */
int WtBitMask(int port, int and, int wt, int sec)
{
long counter;
for(counter=sec*1000L;counter>0;counter--){
int i;
i=inportb(port);
if((port&7)==7) Last1X7=i;
if((i&and)==wt) return(0);
delay(1);
}
return(1);
}

/* произвести сброс */
int ResetDrive(int port)
{
int i;
outportb(port+7,8); /* программный сброс */
outportb(port+0x206,0xe); /* аппаратный сброс */
delay(10);
outportb(port+0x206,8);
delay(10);
for(i=0;i<200;i++)
if((inportb(port+7)&0x88)==0)return(0);
else delay(10);
return(1);
}


/* найти не более <maxdetect> ATAPI-cd и
записать их описатели в таблицу DrvTbl*/
int FindAtapiCD(int maxdetect, int *DrvTbl)
{
int devnum;
int totaldev=0;
for(devnum=0;(Atp[devnum].port!=0)&&(totaldev<=maxdetect);devnum++){
register int port=Atp[devnum].port;
int i;
/* адрес устройства */
outportb(port+6,Atp[devnum].ms?0xA0:0xB0);
delay(1);
if(inportb(port+7)==0xFF)continue;
if(inportb(port+7)&0x80){
/* м.б. оживится ? */
if(ResetDrive(port))continue;
}
outportb(port+4,0);
outportb(port+5,0);
outportb(port+7,0xEC);
for(i=0;i<20;i++){
delay(1);
if((inportb(port+4)==0x14)&&
   (inportb(port+5)==0xEB)){
word devcode;
/* есть ATAPI-устройство, анализируем подробнее */
delay(1);
outportb(port+7,0xA1);
for(i=0;i<100;i++)
if(inport(port+7)&0x80)delay(1);
else goto okcont;
goto cont;

okcont:
delay(10);
devcode=inport(port);
for(i=0;i<255;i++)inport(port);
/* это CD ? */
if((devcode&0x1F00)!=0x500)break;
/* У него 12 бит в AP ? */
if(devcode&1)break;
*DrvTbl++=devnum;
totaldev++;
break;
   }
}
cont:;
}
return(totaldev);
}


/* запретить прерывания - дабы умные cd-драйвера не мешались */
int DsbIrq(int devnum)
{
int inum=Atp[devnum].irq;
int oldst;
if(inum==0)return(0);
if(inum>=8){
oldst=inportb(0xA1);
outportb(0xA1,oldst|(1<<(inum-8)));
return(!(oldst&(1<<(inum-8))));
}
oldst=inportb(0x21);
outportb(0x21,oldst|(1<<(inum)));
return(!(oldst&(1<<(inum))));
}

/* разрешить прерывание от cd - при завершении работы */
void EndIrq(int devnum)
{
int inum=Atp[devnum].irq;
if(inum==0)return;
if(inum>=8){
outportb(0xA1,
inportb(0xA1)&(~(1<<(inum-8))));
}
else{
outportb(0x21,
inportb(0x21)&(~(1<<inum)));
}
}

/* Выполнить ATAPI-команду:
 drive - устройство
 dir    - 1 - чтение, 0 - запись данных в CDD
 AP - буфер с ATAPI-пакетом
 buffer - буфер с данными (NULL, если не нужен)
 bufflen- длина выводимых данных или макс. размер вводимых
на выходе:
 -1 - была ошибка
 прочее - размер пересланного блока (в байтах)
*/
static word PrefIOBlock=0x8000;  /* размер блока пересылки в словах */
static byte DontResetFlg=0; /* не сбрасывать при неготовности */

int ExecATAPICMD(int drive, int dir, word *AP, word *buffer, word bufflen)
{
int port;
int i;
int readed=0;
int size;
port=Atp[drive].port;
/* выберем активное устройство */
outportb(port+6,Atp[drive].ms?0xA0:0xB0);

rerd:

Last1X7=inportb(port+7);
if(Last1X7&0x88){ /* не очень готов - попробуем исправить положение */
if(DontResetFlg)return(-1);
ResetDrive(port);
/* ждем завершения команды сброса */
if(WtBitMask(port+7,0x80,0x0,10))return(-1); /* не готов */
goto rerd;
}
/* установим размер блока */
{
 register word pl;

 if(PrefIOBlock>bufflen)pl=bufflen;
 else pl=PrefIOBlock;
 outportb(port+4,pl);
 outportb(port+5,pl>>8);
}
/* запретим всякие хитрые обмены */
outportb(port+1,0);
/* все готово к работе  - приступим к передаче пакета */
outportb(port+7,0xA0);
/* ждем готовности не более 3х секунд (можно и меньше) */
if(WtBitMask(port+7,0x89,8,3))return(-1);
/* выведем пакетик */
disable();
for(i=0;i<6;i++) outport(port,*AP++);
enable();

/* точка входа цикла приема блоков */
GetNextBlk:
/* здесь ждем до 30 секунд */
WtBitMask(port+7,0x80,0x00,30);
/* пакет воспринят, а запрос выполнен -
получим размер и направление передачи */
size=inportb(port+4) | (inportb(port+5)<<8);
Last1X7=inportb(port+7);
if(Last1X7&1)return(-1); /* ошибка выполнения команды */
if(Last1X7&8){ /* нужно что-то пересылать */
if(inportb(port+2)&2){
 /*из CD */
if(dir==1 && buffer != NULL ){
/* прочтем предлагаемое */
   while(size>0){
int i=inport(port);
size-=2;
if(bufflen<1)break;
*buffer++=i;
readed+=2;
bufflen-=2;
   }
}
/* пропустим ненужный остаток */
while((size-=2)>0){inport(port);}
}
else{
/* в CD */
if(dir==0 && buffer!=NULL ){
   while(bufflen>0 && size > 0){
if(bufflen<1)break;
outport(port,*buffer++);
bufflen-=2;
readed+=2;
size-=2;
   }
}
/* добросим остаток нулями */
while((size-=2)>0){outport(port,0);}
}
goto GetNextBlk;
}
/* пересылать больше не нужно - команда завершена */
Last1X7=inportb(port+7);
if(Last1X7&1){
/* были ошибки */
return(-1);
}
return(readed);
}


/***************************************************************/
/*              это тестовый проигрыватель CD                  */
/* для упрощения интерфейса проигрывает только первые 10 треков*/
/***************************************************************/

/* примитивная спрашивалка строки */
char *AskStr(char *quest)
{
static char str[80];
rtt:
printf(quest);
fflush(stdin);
if(fgets(str,79,stdin)==NULL)exit(1);
return(str);
}


typedef struct{
word Params1;
word scsi1;
byte len;
word dummy2;
byte Scsi2;
char Manuf[8];
char Prod[0x16];
char Rev[4];
}Inf12Blk;

typedef struct{
word bkllen;
byte state;
byte undef[9];
byte flags1, flags2, flags3, flags4;
word maxspeed;
byte undef2;
byte audiosteps;
word bufsize;
word curspeed;
word dummy[10];
}Cmd5AInfo;

typedef struct{
word st1;
byte err0;
byte    dummy1[9];
byte err1;
byte err2;
byte dummy2[4];
}Inf3Blk;

typedef struct{
byte res1;
byte CA;
byte number;
byte res2;
byte Start[4];
}OneTrk0;

typedef struct{
word Len;
byte BegTrk;
byte EndTrk;
OneTrk0 Trk[11];
}TOC10;

Cmd5AInfo Buf5A2A;
Inf12Blk Info12Buf;
Inf3Blk  Info3Buf;
TOC10 TrkBuf;

/* ATAPI-пакеты для разных запросов */
word ClosePkt[6]={0x1B,0,3,0,0,0};
word EjectPkt[6]={0x1B,0,2,0,0,0};
word Info5A2A[6]={0x5A,0xAA,0,0,0x1C,0};
word Info12[6]={0x12,0,sizeof(Inf12Blk),0,0,0};
word LockPkt[6]={0x1E,0,1,0,0,0};
word UnlockPkt[6]={0x1E,0,0,0,0,0};
word Info3[6]={0x3,0,sizeof(Inf3Blk),0,0,0};
word RdToc[6]={0x243,0,0,1,sizeof(TOC10),0};
word PlaySt[6]={0x47,0,0,-1,255,0};
word ReadSc[6]={0xBE,0,0,0,0,0};
word ReadScM[6]={0xB9,0x0,0x0,0x0,0x0,0};


/* Буфер для чтения секторов */

#define MaxSect 16U

byte Buffer[2352U*MaxSect];

void main(void)
{
int devtbl[8];
int workdrv;
int maxdrv;
int i;
maxdrv=FindAtapiCD(8,devtbl);
printf("Detected %d ATAPI CD-ROM drive(s):\n",maxdrv);
if(maxdrv<1)return;
{
int i;
for(i=0;i<maxdrv;i++){
printf("%1.1d: %3.3Xh:%c (irq %d)\n",i+1,
Atp[devtbl[i]].port,
Atp[devtbl[i]].ms?'M':'S',
Atp[devtbl[i]].irq);
}
if(maxdrv>1){
do{
  workdrv=atoi(AskStr("Select work drive>"));
}while((workdrv<1)||(workdrv>maxdrv));
workdrv=devtbl[workdrv-1];
}
else { AskStr("Press Enter to continue....");
workdrv=devtbl[0];
}
}
/* рабочий диск выбран */
DsbIrq(workdrv);

redrawscr:
clrscr();

gotoxy(1,15);
cprintf(
" 0-9 - Start play at track X       E - Eject disk\n\r"
" R   - Rescan  track list          C - Close tray\n\r"
" I   - Some drive info             M - Manufacturer Info\n\r"
" L   - Lock tray                   U - unlock tray\n\r"
" X   - Error type                  W - write CD to disk\n\r"
" Z   - Redraw screen\n\r"
" Esc - quit");
gotoxy(1,22);
cprintf(" Select >");
rein:
gotoxy(10,22);
while(kbhit())getch();
i=getch();
gotoxy(1,23);clreol();
switch(i){
/* треки  - запуск на проигрывание */
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':i-='0';
cprintf("Start playing....");
PlaySt[1]=TrkBuf.Trk[i].Start[1]<<8;
PlaySt[2]=TrkBuf.Trk[i].Start[2]|(TrkBuf.Trk[i].Start[3]<<0x8);

PlaySt[3]=TrkBuf.Trk[i+1].Start[1]|(TrkBuf.Trk[i+1].Start[2]<<0x8);
PlaySt[4]=TrkBuf.Trk[i+1].Start[3]<<8;

if(ExecATAPICMD(workdrv,0,PlaySt,NULL,0)!=-1)cprintf("Ok");
else printf("Fail");
break;
/* выбросить трей */
case 'E':
case 'e':
cprintf("Eject disk....");
if(ExecATAPICMD(workdrv,0,EjectPkt,NULL,0)!=-1)cprintf("Ok");
else printf("Fail");
break;
/* втянуть диск */
case 'C':
case 'c':
cprintf("Close tray....");
if(ExecATAPICMD(workdrv,0,ClosePkt,NULL,0)!=-1)cprintf("Ok");
else printf("Fail");
break;
/* смешанная информация (команда 5A/2A) */
case 'I':
case 'i':
if(ExecATAPICMD(workdrv,1,Info5A2A,(void*)&Buf5A2A,sizeof(Buf5A2A))>0){
cprintf("MaxSpd: %d, CurSpd: %d, Buff: %d Kb",
GetMSBWord(Buf5A2A.maxspeed),
GetMSBWord(Buf5A2A.curspeed),
GetMSBWord(Buf5A2A.bufsize));
}
else cprintf("Fail");
break;
/* информация от производителя */
case 'M':
case 'm':
if(ExecATAPICMD(workdrv,1,Info12,(void*)&Info12Buf,sizeof(Info12Buf))>0){
cprintf("Manuf: [%8.8s], Prod: [%16.16s], Rev: [%4.4s]",
Info12Buf.Manuf,
Info12Buf.Prod,
Info12Buf.Rev);
}
else cprintf("Fail");
break;
/* блокировка трея */
case 'l':
case 'L':cprintf("Lock tray....");
if(ExecATAPICMD(workdrv,0,LockPkt,NULL,0)!=-1)cprintf("Ok");
else printf("Fail");
break;
/* разблокировка трея */
case 'u':
case 'U':cprintf("Unlock tray....");
if(ExecATAPICMD(workdrv,0,UnlockPkt,NULL,0)!=-1)cprintf("Ok");
else printf("Fail");
break;
/* расширенная информация об ошибках */
case 'X':
case 'x':
if(ExecATAPICMD(workdrv,1,Info3,(void*)&Info3Buf,sizeof(Info3Buf))>0){
cprintf("Err0: %3.3Xh, Err1: %3.3Xh, Err2: %3.3Xh",
Info3Buf.err0,
Info3Buf.err1,
Info3Buf.err2);
}
else cprintf("Fail");
break;
/* перечитать список дорожек */
case 'R':
case 'r':
if(ExecATAPICMD(workdrv,1,RdToc,(void*)&TrkBuf,sizeof(TrkBuf))>0){
gotoxy(1,1);
cprintf("Num   Ctrl/Addr   TrNum    Start");
{
 for(i=0;i<10;i++){
   cprintf("\n\r");
   clreol();
   if(i<TrkBuf.EndTrk){
    cprintf("%2.2d    %3.3Xh        %2.2X     %2.2d:%2.2d:%2.2d",
i,
TrkBuf.Trk[i].CA,
TrkBuf.Trk[i].number,
TrkBuf.Trk[i].Start[1],
TrkBuf.Trk[i].Start[2],
TrkBuf.Trk[i].Start[3]);
   }


 }
}
}
else cprintf("Fail");
break;
/* чтение секторов на диск (от начала и пока не остановят) */
case 'w':
case 'W':{FILE *img;
  word len;
  long CurSector=0;
while(kbhit())getch();
img=fopen("CDImage.bin","wb");
if(img==NULL)cprintf("Can't open save file !");
cprintf("Copying sectors. Press any key to abort [");
do{
cprintf("/");
StoreLBAToMSF(CurSector,((byte*)ReadScM)+3);
StoreLBAToMSF(CurSector+MaxSect,((byte*)ReadScM)+6);
((byte*)ReadScM)[9]=0x10;
len=ExecATAPICMD(workdrv,1,ReadScM,(void*)Buffer,sizeof(Buffer));
if(len==0xFFFF){ cprintf("]CD read fail");goto ecpy;};
if(len==0){ cprintf("]CD return zero bytes");goto ecpy;}
cprintf("%u\\",len);
if(fwrite(Buffer,len,1,img)!=1){
cprintf("]Error write to disk");
goto ecpy;
}
CurSector+=MaxSect;
}while(!kbhit());
while(kbhit())getch();
cprintf("]Copy stopped");
ecpy:
cprintf("(%ld)",CurSector);
fclose(img);
break;
}
case 'z':
case 'Z':goto redrawscr;
/* выход из програмы */
case 0x1b:goto finch;
case 0: goto rein;
}
goto rein;
finch:
clrscr();
}


#########################################################################

PS/ Изначально этот документ составлялся исключительно для внутреннего
    использования по причине невозможности найти фирменное описание
    стандарта на ATAPI-CD.
    Поскольку вся информация бралась из дизассемблированных драйверов,
    исходных текстов Linux'а, отдизассемблированной прошивки ACER665,
    a также из описания SCSI-пакетов и стандарта на ATAPI, то вполне
    возможны определенные расхождения со стандартом (в существовании
    которого я не уверен). Несмотря на это, мне кажется, что даже такое
    описание представляет определенную ценность.

    В данное описание не попала команда специального чтения данных
    (028h/0A8h) - у меня нет четких данных о ее работе, а также
    несколько других, которые не используются в драйверах и поддерживаются
    не всеми приводами. Это касается команд потрекового проигрывания
    Audio-CD, команд смены диска в многодисковых приводах и т.п.

    У меня осталась еще кое-какая информация, например, тексты CD-драйверов,
    прошивок и т.п., которые были сочтены несущественными или излишне
    громоздкими. Если необходимо, можно вставить в этот документ выдержки из
    драйверов.

    Для любитетлей "подробных описаний" могу порекомендовать стандарт
    SCSI-2 (X3T9.2).Там есть большое количество интересной информации,
    но солидный объем (более 20 тыс. строк или около 1.7 Mb), некоторые
    отличия SCSI от ATAPI и "замусоренность" лишними деталями усложняют
    получение нужных сведений.

    При необходимости более детального ознакомления с процессом обмена
    (обмен по DMA, перекрывающиеся команды и т.п.) можно прочитать стандарт
    на ATAPI устройства (X3T10). Однако, описание конкретных CD команд там
    отсутствует (есть ссылка на SCSI).

    Ревизии:
    10.08.1996  - собраны и как-то систематизированы отрывочные данные
    19.09.1996  - первый раз отдан на растерзание.
    20.12.1996  - добавлено кое-что из ATAPI и сказевого описания.
    14.02.1997  - уточнены термины, добавлено описание некоторых битов,
                  регистров и команд.
    01.03.1997  - еще одно мелкое исправление терминов.
    23.03.1997  - подправлено описание битов,
                  добавлена тестовая программа,
                  убрано "hex-по умолчанию",
                  убраны ошибочные сведения о бите 10h в 177h и другие
                  ошибки в алгоритме выполнения команды.
    29.03.1997  - В команде 4B на хвосте пакета был один лишний байт.

Автор статьи Константин Норватов (Konstantin Norvatoff, KonNor): konnor@small.spb.su



 
     

Изготовление и модернизация фонтанов. Аренда и прокат фонтанов. Дарите радость людям! Покупайте наши изделия!

поднятся наверх страницы о диммерах

На Главную
Новости
Наверх страницы

поднятся наверх страницы о диммерах      

Светомузыкальные фонтаны, Поющие фонтаны, прокат фонтанов, аренда фонтанов, Динамические фонтаны,

хочу купить
фонтан

Светомузыкальные фонтаны, Поющие фонтаны, прокат фонтанов, аренда фонтанов, Динамические фонтаны,

Контакты

Светомузыкальные фонтаны, Поющие фонтаны, прокат фонтанов, аренда фонтанов, Динамические фонтаны, musidora@rambler.ru

Последнее обновление 09.08.2009

Инженер и веб-мастер Богданов Андрей Александрович Water LAB ©