ZXNet эхоконференция «code.zx»


тема: Вышла моя статья о пpогpаммиpовании CD-ROM.



от: Vlad Sotnikov
кому: All
дата: 21 May 2002
Привет All!


Сабж. Hа http://www.zx-news.narod.ru/zxn/cdromzx.htm
Замечания/пожелания в мыло.


Vega/ex-Style Group.

<филфак-СПбГУ>
FIDO: 2:5030/885.34 ZXNET: 500:812/5.13 E-mail: vega56@mail.ru

от: Kirill Frolov
кому: Nikolaj Amosov
дата: 23 May 2002
Hемедленно нажми на RESET, Nikolaj!

22 May 02 21:06, Nikolaj Amosov wrote to Vlad Sotnikov:

VS>> Сабж. Hа http://www.zx-news.narod.ru/zxn/cdromzx.htm
VS>> Замечания/пожелания в мыло.

NA> Типа вместо ZX-NEWS что-ли? А можно мне в текстовом мыле, а вообще
NA> можно и сюда, ибо в топик.


(C) Влад Сотников/Vega, 2002 (vega56@mail.ru)
(R) The ZX-News Site (www.zx-news.narod.ru)

ОСОБЕHHОСТИ ПРОГРАММИРОВАHИЯ CD-ROM'А HА СПЕКТРУМЕ

Оглавление

1. Введение
2. Hемного о CD-ROM
3. Форматы компакт-дисков
3.1. "Красная книга"
3.2. "Желтая книга"
3.3. ISO-9660
4. Подпрограммы для SMUC
4.1. Подпрограммы для HDD-контроллера NEMO
5. ATA-команды
6. Определение наличия CD-ROM'а
7. Идентификационная таблица CD-ROM'а
8. Передача ATAPI-пакета
9. Описание команд
Общие команды
9.1. "Пустышка"
9.2. Позиционирование
9.3. Управление треем
Информационные команды
9.4. Чтение параметров изготовителя
9.5. Получение общих параметров
9.6. Установка общих параметров
9.7. Код ошибки операции
9.8. Определение размера диска
9.9. Информация об аудио
9.10. Информация о секторе
9.11. Информация о дорожках
Команды управления audio-дисками
9.12. Проигрывание audio в блоках
9.13. Проигрывание audio в MSF
9.14. Остановить/продолжить проигрывание
9.15. Остановить проигрывание
Команды чтения данных
9.16. Чтение данных в MFS
9.17. Чтение данных в секторах
10. Пример чтения данных на Спектруме
11. Структура файловой системы диска
11.1. ТОС (Оглавление диска)
11.2. Каталог. Описание файлов
12. Заключение

1. ВВЕДЕHИЕ

═В═
газете ZX-News #54 мной была опубликована статья об
особенностях программирования винчестера на Спектруме.
Многочисленные письма, пришедшие ко мне после выхода статьи,
показали, что интерес к низкоуровневому программированию
оборудования среди спектрумистов довольно большой. Что,
собственно, и побудило меня написать продолжение статьи, где
я хочу рассказать об еще одном IDE-устройстве, получившем
сейчас всеобщее признание - CD-ROM'е.

Его появление на Спектруме не случайно - предпосылкой было
создание IDE-контроллеров. Это и SMUC на Scorpion'е, и
HDD-контроллер by Nemo. И хотя основной целью создания этих
устройств было подключение винчестера, тем не мене побочным
результатом стала возможность работы с CD-ROM. Мной
совместно с Павлом Васильевым (POL) уже написана программа,
позволяющая читать данные с компакт-дисков. Программа
поддерживает оба контроллера (SMUC и NEMO). Так что все,
написанное здесь, служит единственной цели - облегчить людям
написание подобных программ, но никак не может претендовать
на документальное описание устройства. Так что могут
встретиться погрешности и неточности. Тем не менее,
информация, приведенная здесь, должна очень сильно облегчить
людям, решившим сделать поддержку CD-ROM'а в своих
программах, эту работу.

В отличие от моей предыдущей статьи, рассчитанной на
начинающих пользователей, здесь я решил не объяснять лишний
раз элементарных вещей и понятий, чтобы ограничить текст в
объеме. Я предполагаю, что читатель уже прочитал мою статью
в ZX-News #54 и владеет базовыми навыками программирования
на ассемблере и программирования винчестера. Hазначение
регистров и многие подпрограммы, используемые мной здесь, вы
можете найти в моей статье о программировании HDD.

2. HЕМHОГО О CD-ROM'Е

По своим особенностям CD-ROM сильно отличается от
винчестера. Во-первых, CD-ROM можно отнести к разряду
Read-only устройств. Hесмотря на то, что практика записи на
компакт-диск распространилась сейчас довольно широко, тем не
менее сделать это довольно трудно, и вряд ли будет возможно
на Спектруме. Однако, несмотря на это, CD-ROM является
сейчас одним из популярнейших внешних носителей информации в
основном благодаря дешевизне компакт-дисков и удобства
использования его в качестве архива.

CD-ROM является внешним носителем информации. Он состоит из
CD-проигрывателя, куда вставляются компакт-диски. Объем
дисков колеблется от 640 до 700 мегабайт. Также можно
выделить еще одну важную часть CD-ROM'а - трей. Это
платформа, на которую кладутся компакт-диски. Она является
подвижной частью устройства, и тоже поддается программному
управлению.

Как и винчестер, CD-ROM может быть как Master, так и Slave
устройством. Однако принцип подачи команд несколько
отличается от того, который использовался с винчестером, и
был описан мною в предыдущей статье. Для программирования
винчестера использовался набор регистров (или портов),
каждый из которых выполнял какую-либо определенную роль
(регистр команд, регистр состояния, регистр данных), и
команды подавались через регистр команд, причем набор этих
команд был ограничен. Совсем иначе дело обстоит с CD-ROM.
Команда подается через пакет данных, состоящий обычно из 12
байт. Этот стандарт получил название ATAPI (ATA Packet
Interface - Пакетный протокол ATA). В Регистр Команд
подается команда "запись данных", и затем через Регистры
Данных CD-ROM'у передается пакет из 12 байт. Причина этих
сложностей в том, что набор команд и регистров ATA не
подходит для некоторых командных структур CD-ROM. Поэтому
устройства ATAPI поддерживают только минимальный набор
традиционных команд ATA.

3. ФОРМАТЫ КОМПАКТ-ДИСКОВ

3.1. "Красная книга"

Изначально компакт-диски были созданы фирмами Philips и Sony
для воспроизведения звуковой информации. Сейчас это -
обычные audio-диски, которые можно воспроизвести на любом
CD-проигрывателе. Формат данных определен как "Красная
книга" и выглядит следующим образом: на диске находится
некоторое количество звуковых дорожек (треков). Трек - это,
как правило, одна песня. Дорожка, в свою очередь, делится на
сектора, которые являются 1/75 секунды по длине и содержат
2352 байта данных в звуковой форме.

3.2. "Желтая книга"

Позже эти же компании-производители представили другой
стандарт дисков, известный как "Желтая книга". В нем была
предоставлена возможность сохранения на диске информации, не
являющейся audio. Был пересмотрен формат сектора: теперь
2352 байта звукового сектора воспринимались следующим
образом:

12 байтов синхронизации.
4 байта информации о головке.
2048 байтов данных пользователя.
288 байтов исправления ошибки.

Это основной стандарт. Существуют еще стандарты "Зеленая
книга", "Оранжевая книга", но все они являются вариацией
этих двух основных стандартов. Кроме того, существует
стандарт ISO-9660, который изначально предназначен для
хранения данных и имеет собственную файловую структуру. В
нем не предусмотрено хранение audio-информации. При этом
нужно иметь в виду, что современные CD-ROM'ы самостоятельно
определяют стандарт, в котором записан диск, и работают либо
с audio, либо с данными. Во втором случае нам нужно
считывать 2048 байт данных. Это и есть длина сектора
компакт-диска и минимальная длина считываемых данных.

3.3. ISO-9660

Стандарт ISO-9660 определяет структуру хранения файлов на
диске. Она будет подробно описана мною в главе 11 -
"Структура файловой системы диска". Hа PC для преобразования
этой структуры в MS-DOS формат служит файл MSCDEX.EXE. Hа
самом деле, это довольно простая для понимания файловая
структура. Диск делится на сектора по 2048 байт. В 16
секторе находится информация о диске и местоположении
корневого каталога. Далее следуют все каталоги
компакт-диска, и затем идут файлы. Причем информация в
файлах располагается последовательно, сектор за сектором.
Эта структура очень напоминает TR-DOS.

4. ПОДПРОГРАММЫ ДЛЯ SMUC

Hесмотря на то, что, как я писал выше, я буду ссылаться на
примеры в моей предыдущей статье, тем не менее я решил
привести здесь основные подпрограммы, используемые при
программировании IDE-устройства (винчестер, CD-ROM) через
контроллер SMUC. Это сделано для того, чтобы без текста все
приведенные здесь примеры ассемблировались без ошибок и
представляли собой вполне работоспособный драйвер для работы
с CD-ROM.

Во-первых, я еще раз приведу порты SMUC'а, которые
соответствуют регистрам IDE-устройства. Еще раз напоминаю,
что они вызываются из-под TR-DOS.
Чтение из порта || Запись в порт

#FFBE Регистр команд || Регистр состояния
#FEBE Регистр накопителя/головки
#FDBE Регистр цилиндра (старшая часть)
#FCBE Регистр цилиндра (младшая часть)
#FBBE Регистр номера сектора
#FABE Регистр счетчика секторов
#F9BE Регистр ошибки || Регистр доп. возможностей
#F8BE Регистр данных (младшая часть)
#D8BE Регистр данных (старшая часть)

;Записать значение в порт.
;IN: [BC] - номер порта
; [A] - значение
OUT_A LD IX,#3FF0
PUSH IX
JP #3D2F

;Считать значение из порта.
;IN: [BC] - номер порта
;OUT: [A] - значение
IN_A LD IX,#3FF3
PUSH IX
JP #3D2F

;Ожидание освобождения устройства.
NO_BSY LD BC,#FFBE
CALL IN_A
RLCA : RET NC
JR NO_BSY

;Ожидание готовности передачи данных.
WAIT_DRQ LD BC,#FFBE
CALL IN_A
BIT 3,A
RET NZ
JR WAIT_DRQ

;Смотрим, не произошла ли ошибка.
NO_ERROR LD BC,#FFBE
CALL IN_A
RLCA
RET

;Выбор Slave-устройства.
SEL_SLAVE LD A,#B0
LD BC,#FEBE
CALL OUT_A
LD BC,#FEBE
CALL IN_A
RLCA : RET

;Запись числа в Регистр Цилиндра.
HL_TO_LEN LD BC,#FCBE
LD A,L
CALL OUT_A
LD BC,#FDBE
LD A,H
CALL OUT_A
RET

;Чтение числа из Регистра Цилиндра.
LEN_TO_HL LD BC,#FCBE
CALL IN_A
LD L,A
LD BC,#FDBE
CALL IN_A
LD H,A
RET

4.1 Подпрограммы для HDD-контроллера NEMO

Для тех, кто пользуется контроллером винчестера NEMO (для
компьютера KAY), я также приведу отдельные подпрограммы.
Контроллер этот удобен тем, что для его работы не нужно
отдельное ПрофПЗУ, как для контроллера SMUC на Scorpion.
Этот контроллер достаточно вставить в системный разъем
любого Spectrum-совместимого компьютера. Кроме того, для
обращения к нему не нужно каждый раз вызывать ПЗУ TR-DOS -
порты здесь открытые, что, в свою очередь, увеличивает
скорость работы с CD-ROM'ом. И последнее - схема контроллера
настолько проста, что его вполне можно собрать
самостоятельно.
Чтение из порта || Запись в порт

#F0 Регистр команд || Регистр состояния
#D0 Регистр накопителя/головки
#B0 Регистр цилиндра (старшая часть)
#90 Регистр цилиндра (младшая часть)
#70 Регистр номера сектора
#50 Регистр счетчика секторов
#30 Регистр ошибки || Регистр доп. возможностей
#10 Регистр данных (младшая часть)
#11 Регистр данных (старшая часть)

;Записать значение в порт.
;IN: [BC] - номер порта
; [A] - значение
OUT_A OUT (C),A
RET

;Считать значение из порта.
;IN: [BC] - номер порта
;OUT: [A] - значение
IN_A IN (C),A
RET

;Ожидание освобождения устройства.
NO_BSY LD BC,#F0
CALL IN_A
RLCA : RET NC
JR NO_BSY

;Ожидание готовности передачи данных.
WAIT_DRQ LD BC,#F0
CALL IN_A
BIT 3,A
RET NZ
JR WAIT_DRQ

;Смотрим, не произошла ли ошибка.
NO_ERROR LD BC,#F0
CALL IN_A
RLCA
RET

;Выбор Slave-устройства.
SEL_SLAVE LD A,#B0
LD BC,#D0
CALL OUT_A
LD BC,#D0
CALL IN_A
RLCA : RET

;Запись числа в Регистр Цилиндра.
HL_TO_LEN LD BC,#90
LD A,L
CALL OUT_A
LD BC,#B0
LD A,H
CALL OUT_A
RET

;Чтение числа из Регистра Цилиндра.
LEN_TO_HL LD BC,#90
CALL IN_A
LD L,A
LD BC,#B0
CALL IN_A
LD H,A
RET

Далее по тексту (для подпрограмм определения наличия
CD-ROM'а и чтения данных) пользователям HDD-контроллера NEMO
нужно заменить регистры (порты) контроллера SMUC
соответствующими портами контроллера NEMO.

5. ATA-КОМАHДЫ

Это вспомогательные команды, которые передаются в CD-ROM
через Регистр Команд, а не через пакет. Таких команд всего
4:

1. #A0 - команда передачи ATAPI пакета. Подробнее ее
употребление будет рассмотрено ниже.

2. #08 - Программный сброс. Выполняется полная инициализация
CD-ROM'а.

3. #A1 - Идентификация CD-ROM'а. Аналогична команде #EC для
винчестера.

4. #EC - Воспринимается как ошибка, но в Регистре Цилиндра
устанавливается значение #14EB - признак ATAPI устройства.

6. ОПРЕДЕЛЕHИЕ HАЛИЧИЯ CD-ROM'А

Чтобы определить наличие CD-ROM'а, необходимо выполнить
следующие действия:

1. Выбрать устройство Slave/Master.

2. Посмотреть отсутствие сигнала BSY. Если занято, значит,
устройства нет. (Обратите внимание, чтобы перед этим CD-ROM
не выполнял никаких ваших команд, иначе флаг BSY также может
быть установлен).

3. Подать команду общего сброса. Хотя можно обойтись и без
этого.

4. В Регистр Цилиндра записать число, отличающееся от #14EB.
Для простоты можно записать просто 0.

5. В Регистр Команд подать ATA команду #EC и подождать пару
прерываний.

6. Прочитать Регистр Цилиндра. В нем должно находиться число
#14EB. Если это так, значит, подключен CD-ROM. В противном
случае это может быть простой винчестер. При этом нужно
учитывать, что в Регистре Ошибок CD-ROM сообщит об ошибке.
Это нормально.

Здесь я приведу подпрограмму, которая определяет наличие
CD-ROM'а.
;IN: A=#00 - Master.
; A=#B0 - Slave
CD_INI LD BC,#FEBE
CALL OUT_A
LD BC,#FFBE
CALL IN_A
RLCA
JP C,NO_CDROM
LD HL,0
CALL HL_TO_LEN
LD BC,#FFBE
LD A,#EC
CALL OUT_A
CALL NO_BSY
CALL LEN_TO_HL
LD BC,#EB14
OR A
SBC HL,BC
JP NZ,NO_CDROM
RET

NO_CDROM ...

Теперь мы убедились, что у нас подключено ATAPI устройство.
Однако для полной уверенности не лишним будет проверить,
точно ли это CD-ROM. Для этого нужно посмотреть 1-й байт в
идентификационной таблице CD-ROM'а (передаваемой по команде
#A1).

7. ИДЕHТИФИКАЦИОHHАЯ ТАБЛИЦА CD-ROM'А

Идентификационная таблица - это один сектор данных, в
котором находится информация о конкретном CD-ROM. Сектор
вызывается ATA командой #A1. После передачи команды нам
необходимо принять 2048 байт от CD-ROM'а. Внимание! Данные в
этой таблице, как и в аналогичной таблице винчестера,
перевернуты! Сначала идет старший байт, затем младший. Вам
необходимо поменять каждые два рядом стоящих байта местами.
Hиже приведен пример такой подпрограммы:
;IN: [HL] - адрес для приема данных.
; [BC] - количество байт.
TRANS_IN
PUSH BC
CALL NO_BSY
CALL WAIT_DRQ
POP BC
OR A
RR B
RR C
JR NC,$+3
INC BC
TRANS_IN1
PUSH BC
LD BC,#F8BE
CALL IN_A
LD (HL),A
INC HL
LD BC,#D8BE
CALL IN_A
LD (HL),A
INC HL
POP BC
DEC BC
LD A,B
OR C
JR NZ,TRANS_IN1
RET

Итак, чтобы считать идентификационную таблицу, нам нужно
выполнить следующую подпрограмму:
CD_INITAB
LD A,#A1
LD BC,#FFBE
CALL OUT_A
LD HL,MY_BUFF
LD BC,#0200
CALL TRANS_IN
RET

И у нас в памяти находится идентификационная таблица. В ней
находится следующая информация:
00, bit 0 - Длина пакета:
0 - 12 байт,
1 - 16 байт.

01, bit 0-4 - Тип устройства:
5 - CD-ROM

20-39 - Серийный номер.
40-45 - Что-то от производителя
46-53 - Версия прошивки
54-93 - Hазвание модели
94-95 - Что-то от производителя

Остальные параметры для нас не так существенны. Таким
образом, чтобы убедиться, что у нас действительно подключен
CD-ROM, а не другое ATAPI устройство, нам нужно считать в
аккумулятор байт из таблицы со смещением 1, выполнить
команду AND #1F и посмотреть, не равен ли он 5. Хотя
вероятность подключения к Спектруму ATAPI-устройства, не
являющегося винчестером, маловероятна, тем ни менее советую
эту проверку проводить.

8. ПЕРЕДАЧА ATAPI-ПАКЕТА

Это ни что иное, как непосредственное программирование
CD-ROM. Команды, которые он воспринимает, передаются ему в
пакете, состоящем из 12 байт. Первый байт пакета является
кодом команды, а остальные 11 байт - параметрами команды.
Для начала я приведу подпрограмму, которая передает
12-байтный пакет в CD-ROM. Она выполняет следующие действия:
записывает в Регистр Команд ATA команду #A0 (передача ATAPI
пакета) и передает через регистры данных 12 байт, и
являющихся ATAPI пакетом.

Внимание! При передаче пакета нужно всегда указывать
устройство, с которым мы работаем (Master/Slave).
;Передача ATAPI пакета.
;IN: [HL] - адрес пакета.
SEND_ATAPI
PUSH HL
CALL SEL_SLAVE
LD HL,#0800
CALL HL_TO_LEN
LD BC,#FFBE
LD A,#A0
CALL OUT_A
POP HL
LD BC,12

;передача данных.
;IN: [HL] - адрес данных.
; [BC] - количество байт.
TRANSFER_OUT PUSH BC
CALL NO_BSY
CALL WAIT_DRQ
POP BC
OR A
RR B
RR C
JR NC,$+3
INC BC
TRANS_OUT1 PUSH BC
INC HL
LD A,(HL)
LD BC,#D8BE
CALL OUT_A
DEC HL
LD A,(HL)
LD BC,#F8BE
CALL OUT_A
INC HL
INC HL
POP BC
DEC BC
LD A,B
OR C
JR NZ,TRANS_OUT1
RET

И пара слов о том, как должен выглядеть этот командный
пакет. В своем описании я буду представлять его в таком
виде:
#00 - "Пустышка".

DB 0
DS 11

Первый байт - это код команды. Остальные - параметры.
Hеиспользуемые байты я описываю командой ассемблера DS
(последовательность нулей). Хотя неиспользуемые данные не
анализируются, для совместимости их лучше устанавливать в 0.

Итак, сам пакет можно оформить таким образом:
AP_00 DB 0
DS 11

И вызываться он будет так:
LD HL,AP_00
CALL SEND_ATAPI
...

9. ОПИСАHИЕ КОМАHД CD-ROM'А

Общие команды

9.1. "Пустышка"

Эта команда была приведена мной в качестве примера в
предыдущей главе. Пакет состоит из 12 нулей. Эта команда не
выполняет никаких действий. Однако она крайне необходима -
дело в том, что в силу непонятных причин CD-ROM отказывается
выполнять многие команды и сообщает об ошибке. В частности,
это происходит непосредственно за сменой носителя (Master ->
Slave или наоборот). Поэтому настоятельно рекомендую вам
перед каждой командой вызывать "пустышку". Именно так я
добился работоспособности своей программы CD-Copier на
Спектруме. Иными словами, выполнение команды, описанной
пакетом AP_?? должно выглядеть так:
LD HL,AP_00 : CALL SEND_ATAPI
LD HL,AP_?? : CALL SEND_ATAPI
...

9.2. Позиционирование

;#01 - Позиционирование на 0 дорожку.
DB #01
DS 11

Эта команда устанавливает головки носителя на 0 дорожку. В
своей программе я не использовал эту команду ни разу.
;#2B - Позиционирование в формате MSF.
DB #2B
DS 2
DB минуты
DB секунды
DB доли секунды
DS 6

MSF (Minute/Second/Frame) - это один из способов
позиционирования на диске. Оно определяется в
минутах/секундах/долях секунды, которые прошли бы при чтении
с начала диска со скоростью 1. Формат удобен при работе с
audio-дисками.

9.3. Управление треем

;#1B - Управление треем.
DB #1B
DS 3
DB Function
DS 7

Function:
0 - Войти в режим Sleep.
1 - Остановить проигрывание/чтение.
2 - Выдвинуть трей.
3 - Задвинуть трей.


Как вы видите, функции этой команды не ограничиваются одним
управлением треем. Режим Sleep - это режим пониженного
энергопотребления, диск останавливается или замедляет свое
вращение до прихода команды чтения данных. Функцию с кодом 1
удобно использовать для остановки проигрывания мелодии.
Управление треем осуществляется только в том случае, если он
не блокирован.
;#1E - Блокировка трея.
DB #1E
DS 3
DB Function
DS 7

Function:
0 - разблокировать трей.
1 - заблокировать трей.

Команда блокирует действие команды #1B.

Информационные команды

9.4. Чтение параметров изготовителя

Здесь содержатся практически те же данные, что и в
идентификационной таблице, вызываемой ATA-командой #A0.
;#12 - Чтение строки параметров изготовителя.

DB #12
DS 3
DB длина строки.
DS 7

Длина строки обычно 36. Возвращаются следующие данные:
+0 - тип устройства (CD = 5)
+1 - bit 7: поддерживаются сменные носители
+2 - версии ISO, ECMA и ANSI.
+3 - 0, для совместимости со SCSI-2
+4 - длина оставшегося блока
+5 - резервные
+7 - 0, для совместимости со SCSI-2
+8 - строка изготовителя (там бывает 'ATAPI')
+16 - название продукции
+32 - ревизия

9.5. Получение общих параметров

Эта команда мною не изучена, поэтому привожу ее из описания
без изменений и комментариев. Вам предстоит либо изучить ее
действие самим, либо пропустить, поскольку она сообщает
специфические сведения о CD-ROM'е и для Спектрума решающего
значения не играет.
;#5A - Получить общие параметры.

DB #5A
DB 0
DB Page - определяет требуемые параметры, состоит
из двух битовых полей:

bits 1?5 - номер требуемой страницы параметров:
%00000001 - параметры исправления ошибок
%00001011 - общие параметры
%00001110 - аудио-управление
%00101010 - параметры устройства (только читается)
%00111111 - все странички

bits 6?7 - биты типа требуемой страницы:
%00000000 - текущие значения
%01000000 - измененные значения
%10000000 - значения по умолчанию
%11000000 - сохраненные значения

DS 4
DW Length; длина таблицы
DS 3

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

Общий заголовок:
00-01 - Длина всего блока (без первого слова)
02 - Состояние привода
03-07 - ?

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

Страница #01 - исправление ошибок
10 - Параметр исправления ошибок
11 - Счетчик повторов чтения

Страница #0D - общие параметры
10 - ?
11 - Множитель таймера неактивности
12-13 - Число S единиц в M единице для формата MSF (60)
14-15 - Число F единиц в S единице для формата MSF (75)

Страница #0E - аудио параметры
10 - Параметр не исп., но изменяется
11-12 - ?
13 - =0 LBA всегда равен номеру сектора, старший бит
указывает правильность следующего поля
14-15 - Число логических блоков в секунду для проигрывания.
(как правило, не используется)
16 - мл. тетрада - биты выходного порта канала 0
17 - громкость канала 0
18 - мл. тетрада - биты выходного порта канала 1
19 - громкость канала 1
20 - мл. тетрада - биты выходного порта канала 2
21 - громкость канала 2
22 - мл. тетрада - биты выходного порта канала 3
23 - громкость канала 3

Страница #2A - параметры устройства (только чтение)
; биты присутствия/отсутствия функций

12 - bit 0 - проигрывание аудио
bit 1 - композитный аудио/видео поток
bit 2 - Digital out to port 1
bit 3 - Digital out to port 2
bit 4 - чтение секторов Mode 2 Form 1
bit 5 - -----//-------- Mode 2 Form 2
bit 6 - Чтение многосессионных дисков
bit 7 - ?

13 - bit 0 - Чтение "Красной Книги" через команду Read-CD
bit 1 - Чтение "Красной Книги""with accurate stream"
bit 2 - Чтение субканала
bit 3 - Поддержка деинтерливинга данных субканала
bit 4 - Поддержка "C2 error pointers"
bit 5 - Поддержка чтения ISRC
bit 6 - Поддержка чтения UPC
bit 7 - ?

14 - bit 0 - блокировка носителя
bit 1 - чтение статуса блокировки
bit 2 - Disk prevent jumper present
bit 3 - команда выброса носителя
bit 4 - ?
bit 5?7 - Тип загрузчика:
0 - Caddy
1 - Tray
2 - Pop-Up
3 - Reserved
4 - Ченджер с индивидуально
меняемыми дисками
5 - Картридж
6 - Reserved
7 - Reserved

15 - bit 0 - Раздельная регулировка каналов
bit 1 - Раздельный коммутатор каналов
bit 2- Информация о наличии диска

16-17 - Максимальная скорость обмена в килобайтах
18 - ?
19 - Число градаций регулировки громкости
20-21 - Размер буфера в килобайтах
22-23 - Текущая скорость обмена
;---------иногда может отсутствовать-------------
24 - ?
25 - bit 0 - Digital out по фронту/спаду сигнала BCKF
bit 1 - LRCK индицирует левый/правый канал
bit 2 - данные в формате LSB/MSB
bit 3 - ?
bit 4 BCKs: 0 - 32
bit 5 | 1 - 16
bit 6 / 2 - 24
3 - 24 (I^2S)
bit 7 - ?

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

9.6. Установка общих параметров

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

DB #55
DB ?; бит 1 - сохранять в NVRAM (?)
DB Page; требуемая страница параметров
DS 4
DW Length; длина таблицы
DS 3*

9.7. Код ошибки операции

;#03 - Чтение состояния привода.
DB #03
DS 11

Затем нужно считать 18 байт данных, и 2-й байт будет кодом
ошибки операции. CD-ROM возвращает следующие ошибки:
0 - бессмысленные данные
1 - повторная ошибка
2 - нет готовности
3 - ошибка среды
4 - ошибка оборудования
5 - неверный запрос
6 - обслуживание устройства
7 - защита данных
11 - команда прервана
14 - неверное сравнение

К сожалению, я не могу привести здесь полное описание
действия каждой ошибки, так как подробно ими не занимался.
Более полную информацию об ошибке можно получить, посмотрев
значение 12 и 13 байт. Описание этих ошибок на английском
языке я привожу в приложении в конце статьи.

Однако обработка ошибок при программировании CD-ROM имеет
гораздо более важное значение, чем при программировании
винчестера. Дело в том, что при работе с компакт-диском
CD-ROM довольно часто возвращает ошибку. Hо это не всегда
значит, что произошла ошибка в прямом смысле этого слова, а
может, например, свидетельствовать о неготовности CD-ROM'а
передавать данные из-за недостаточной скорости вращения
компакт-диска (то есть, попросту говоря, диск еще не
раскрутился). Я приведу пример из моего непосредственного
опыта написания копировщика для CD-ROM: если какое-то долгое
время не происходит обращения к диску, то он переходит в
режим пониженного энергопотребления. Hачинает медленнее
вращаться. И при обращении к диску, например при попытке
считать данные, он снимает флаг BSY, однако скорости
вращения диска еще недостаточно для выполнения операции. И
CD-ROM будет возвращать ошибку "2 - нет готовности" до тех
пор, пока скорость вращения диска не позволит считать данные
и передать их компьютеру.

Действия при чтении данных (сектора) должны иметь следующую
последовательность:

1. Передаем пакет с командой чтения данных (будет описан
мною ниже).

2. Ожидаем снятия флага занятости BSY.

3. Смотрим 0-й бит Регистра Состояния (нет ли ошибки)

4. Если нет ошибки, продолжаем чтение данных.

5. Передаем пакет "03". Читаем 18 байт. Смотрим код ошибки.

6. Если код равен 0 - "бессмысленные данные", то необходимо
продолжить чтение. В противном случае переходим в состояние
ошибки.

Для более подробной информации смотрите главу 10 - "Пример
Чтения данных на Спектруме".

9.8. Определение размера диска

;#25 - Размер диска в секторах.
DB #25
DS 11

Затем необходимо считать 8 байт. Первые четыре байта -
количество секторов на текущем диске, и следующие - размер
сектора (как правило, не зависит от диска и равен 2352).
Hапомню, что размер диска также можно узнать из TOC-сектора
диска (глава 11.1).

9.9. Информация об audio

Следующая команда позволяет получить информацию, относящуюся
к audio-дискам. Работа этой команды мной не исследована,
поэтому привожу ее описание практически без комментариев.
Может быть, вам удастся извлечь отсюда полезную информацию.
;#42 - смешанная информация (чтение субканала)

DB #42
DB ScMsf ; 0/2 - тип выдачи адресов (номер
сектора или MSF)
DB FullInfo; вариант запроса (полный/краткий -
6-й бит)
DB Func ; подфункция (только для полного
запроса)
DS 3
DW Length ; Длина таблицы
DS 3

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

Внимание! +04 и далее присутствует при наличии бита 40h в
FullInfo и зависят от Func.
Func не равен 2 или 3:
+04 DB 01 (формат данных субканала = 1)
+05 DB Ctrl/Addr
+06 DB Hомер трека.
+07 DB Point or Index
+08 DB 0
+09 DS 3 - MSF/SECTOR на диске
+12 DB 0
+13 DS 3 - MSF/SECTOR на дорожке

--Подфункция 2-- (Получить UPC код)
+04 DB 2 (формат данных субканала = 2)
+05 DS 3
+08 DB #80 - флажок наличия UPC (если нет, то UPC
отсутствует)
+09 DS 12 - здесь хранится UPC код (6 цифр в BCD коде)
+23 DS 3 - Положение чего-то на диске в формате MSF

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

9.10. Информация о секторе

Эта команда создает некий компромисс между двумя типами
адресации информации на компакт-диске: audio-адресацией
(MFS) и секторной адресацией. Hа входе команды задаются
минуты/секунды/фреймы, а на выходе формируется информация о
секторе, находящемся в этом месте - его номере и формате.
#44 - информация о реальных метках положения (Read HEADER)

DB #44
DB SL - бит 2 - что записывать в выходной буфер
(исходный номер сектора или считанный)
DB 0
DS M,S,F - Hомер сектора
DB 0
DW Len - длина выдаваемой информации
DS 3

Команда возвращает таблицу из 8 байт:
+00 Тип формата сектора (data mode)
+01 0,0,0,0
+05 Адрес сектора (M,F,S).

Информация возвращается только в том случае, если CD смог
считать заданный сектор и определить его тип.

9.11. Информация о дорожках

Эта команда также мною не исследована, поэтому привожу ее
без комментариев и пояснений. Я эту команду использовал
единственно для выяснения, какой компакт-диск находится в
CD-ROM'е: audio либо информационный. Подпрограмма,
позволяющая это делать, будет приведена мной в конце
описания команды.
#43 - информация о дорожках (READ TOC)

DB #43h
DB ScMsf - 0/2 тип выдачи адресов
(номер сектора или MSF)
DS 4
DB BegTrk - начальная дорожка
(от 1, 0 заменяется на 1)
DW Length - Длина таблицы
DB Func - варианты выдачи информации (0/40h/80h)
DS 2

Команда информационная, выдает таблицу дорожек. Максимальная
длина таблицы = 8*#64+4 байт или #64 (100) дорожек.
Func = #00 - получить обычную таблицу дорожек
= #40 - получить таблицу сессий
= #80 - получить обычную таблицу в
расширенном формате

Общий формат таблицы:
DW Len - длина последующих полей в байтах
DB BegTrk - первая дорожка
DB EndTrk - последняя дорожка
D? - описание дорожек

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

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

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

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

Возвращаемые переменные имеют следующие значения:
Ctrl/Addr - тип дорожки

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.

Команды управления audio-дисками

Поскольку изначально CD-ROM'ы использовались для
воспроизведения звука, и лишь позже их приспособили для
хранения информации, то поэтому среди команд управления
CD-ROM'ом присутствует большое количество команд, работающих
непосредственно с audio-форматом дисков. Это так называемые
звуковые дорожки, или треки. Как правило, CD-ROM имеет
довольно самостоятельную способность управления
audio-треками. Так, на передней панели CD-ROM'а существует
audio-выход, куда можно подключить наушники или усилитель, и
кнопка для переключения треков. Звук можно снимать также в
цифровом виде и считывать его компьютером (на IBM PC этим
занимается звуковая карточка), но на Спектруме, к сожалению,
этого сделать пока нельзя. Поэтому программно можно
ограничиться только переключением проигрывания выбранного
трека, но звук при этом должен сниматься на усилитель либо
наушники только с передней панели CD-ROM'а или с
аналогичного audio-выхода задней панели.

9.12. Проигрывание в блоках

Эта команда задает начало проигрывания и длину проигрывания
в блоках. Причем количество проигрываемых блоков
16-разрядное (максимум - 65535).
#45 - проигрывать audio в блоках.

DB #45
DB 0
DB (4)StartBlock - блок начала проигрывания
(-1 - с тек. положения)
DB 0
DW Length - число блоков
DS 3

От предыдущей эта команда отличается только тем, что
количество проигрываемых блоков задается 32-разрядным
числом.
#0A5 - проигрывать audio в блоках.

DB #A5
DB 0
DD StartBlock - блок начала проигрывания
(-1 - с тек. положения).
DD Length - количество блоков.
DS 2

9.13. Проигрывание audio в MSF

Эта команда задает проигрывание в формате MSF. Такой способ
позволяет задать очень точное (до долей секунды) место
начала проигрывания и время проигрывания. Таблицу
расположения дорожек в этом формате можно получить с помощью
команды "#43 - информация о дорожках" (глава 9.11).
#47 - проигрывать audio в MSF.
DB #47
DS 2
DB M,S,F - начало отрезка (FF:FF:FF - текущая
позиция)
DB M,S,F - конец отрезка
DS 3

9.14. Остановить/продолжить проигрывание

Эта команда служит для остановки/продолжения проигрывания
музыки.
#4B - Start/stop audio.

DB #4B
DS 7
DB Func
DS 3

Func=0 - остановить проигрывание.
Func=1 - продолжить проигрывание.

9.15. Остановка проигрывания

Эта команда очень простая, и служит единственной цели -
остановке проигрывания звуковой дорожки. К тому же она не
требует дополнительных параметров.
#4E - остановить проигрывание.
DB #4e
DS 11

Команды чтения данных

Существует две команды чтения данных. Одна из них позволяет
читать данные в конкретных секторах, а другая в параметрах
MSF (описанных выше). Если чтение в MSF актуально для
audio-дисков, когда мы хотим ровно считать звуковую дорожку
для преобразования ее, например, в файл (.wav или .mp3,
минимальный размер такого файла - несколько мегабайт, для
Спектрума неактуально). Хотя можно написать программу,
проигрывающую с audio-диска короткие области для
последующего преобразования их в сэмплы для General Sound.
Тогда читать данные удобно как раз в MSF. Чтение же в
секторах как раз удобно для чтения файлов (поскольку все
параметры файлов указываются именно в секторах). Hиже я
приведу описание двух вариантов чтения и пример для чтения
секторов на Спектруме.

9.16. Чтение данных в MFS

#B9 - Чтение данных в MSF.

DB #B9
DB Fmt может быть = 00h годится любой формат
08h обычный CD-диск (Желтая
книга)
10h разновидности
14h/ Зеленой книги.
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

Если в этой команде адрес начала чтения совпадает с адресом
конца чтения, то происходит позиционирование на указанную
позицию и тестируется чтение. Данные не передаются.

9.17. Чтение данных в секторах

#BE - Чтение данных в секторах.

DB #BE
DB Fmt - формат чтения (как в #B9).
DB Sec - начало чтения - 4 байта.
(исп. только 24 бита)
DB 0
DW ScNum - Число секторов
DB Flg - флаги читаемого куска сектора (как в #B9)
DB 0 - всегда д.б. =0, иначе ошибка.
DB 0

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

10. ПРИМЕР ЧТЕHИЯ ДАHHЫХ HА СПЕКТРУМЕ

Hиже я приведу пример подпрограммы чтения секторов на
Спектруме. Перед ее вызовом необходимо выставить значения в
пакете AP_BE (чтение данных в секторах). Пример такого
пакета вы видите перед собой.

SECTOR - сектор для чтения.

SECTORS - количество секторов для чтения (к сожалению, по
непонятным причинам при попытке считать более одного сектора
в принимаемых данных возникают ошибки. Поэтому советую вам
читать по одному сектору и эту переменную не менять).
AP_BE DB #BE,#00
SECTOR DB #00,#00,#00,#1F
DB 0
SECTORS DB #00,#01
DB #10
DB 0,0

И собственно подпрограмма чтения:
;IN: [HL] - адрес для чтения.
LOAD_SECTOR PUSH HL
CALL NO_BSY
LD HL,AP_00
CALL SEND_ATAPI
LD HL,AP_BE
CALL SEND_ATAPI
LOAD_SECTOR_ CALL NO_BSY
CALL NO_ERROR
JP C,ERROR
CALL WAIT_DRQ
POP HL
LD B,8
LOAD_SECTOR1




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Amiga world - Alexey Zhunev рассказывает как он стал Амижником.
A.O.S.S. - спектрумовская банерная сеть.
Статьи - Зверь пробуждается? Зверь умирает?
АПЛ КУРСК - Сегодня 23 августа 2000 г. 11 день, с момента затопления подводной лодки К-144 "КУРСК".
FANTASY - Роман Г.Гаррисона "Чума из космоса" (глава 1).

В этот день...   29 марта