Info Guide
#08
30 ноября 2005 |
|
Железо - CD-ROM - устройство и хитрости подключения.
Беседы о CD CD-ROM - очень капризное устройство.Ма─ ло того, что оно не вполне документировано (впрочем,и в том,что документировано,можно утонуть) - разные модели весьма отличаются программно друг от друга.Наибольший опыт в данном вопросе приобрёл Budder (Константин Зайцев), который опробовал кучу приводов и написал приличный копировщик. SMT, автор эмулятора Unreal Speccy, больше опирается на документацию. В мозговом штурме участвовали, конечно, не только я ( Alone Coder ), Budder и SMT, но и Vega, Kury, ZET-9, AmoNik и др. Хотя многие вопросы по сей день решить не удалось, но думаю, некоторые промежуточ─ ные результаты опубликовать полезно. Пред─ полагается, что читатель уже знаком со статьёй Vega в Абзац #25. Там неверно рас─ писана команда READ TOC (чтение таблицы сессий). Судя по стандарту INF-8020 (это тот самый оригинальный документ,определяю─ щий поведение CD-ROM'ов, но в нём многое стыдливо замалчивается - существует даже справочник "ATA-ATAPI errata" ), FUNC - то же число, что FORMAT, но сдвинутое на 6 бит влево. FUNC>>6 и FORMAT должны совпа─ дать, т.к.новые приводы могут не поддержи─ вать FUNC (пцшные устройства часто распро─ страняются с драйверами, и каждая компания может понимать "стандарт" так, как хочет). Чтобы прочитать данные по всем сессиям, нужно указать BEGTRK=0 и FORMAT=0. Если только последнюю - то FORMAT=1. LENGTН ну─ жно ставить по максимуму ( 2048, старшим байтом вперёд), а привод сам определит, сколько байт передавать (число байт перед обменом кладётся в регистры цилиндра ATA). Команда не срабатывает с первой попытки! Чтобы она сработала, перед её выполнением нужно считать, например, сектор 0. Но я забежал вперёд. Итак, начинаем: SMT: S>> По стандарту ATAPI после reset устрой─ S>> ство обязано держать статус в нуле, S>> чтобы старые до-атапишные bios'ы не S>> опознали его за винт. А главное, никто S>> не обязывает CD-ROM ставить DRDY после S>> команды, это на усмотрение разработчи─ S>> ков устройства. DB> А когда оно включит статус в единицу? После выполнения первой ATAPI-команды (#A0). Но после сброса обязательно 0, в этом отличие от ATA. DB> А что значит ситуация, когда из рег. DB> состояния читается #D0 (то бишь заня─ DB> то) и ни одна прога не хочет видеть DB> CD-ROM? Как его программно сбросить в DB> этой ситуации? Помогает только холод─ DB> ный сброс :( Бит SRST (Soft Reset - #0C, потом #08 в Device Control Register (у Nemo порт #C8)) Потом нужно дать команду #08, дождаться снятия BSY. The ATA software reset mechanism, SRST, (bit 2 in the Device Control Register) cannot be used for ATAPI Devices, because resets issued by the ATAPI driver would also reset any attached hard disk and vice versa. To solve this ATAPI defines an ATAPI Soft Reset command using a reserved ATA opcode which could be decoded by the interface controller hardware. To maintain Master / Slave compatibility with ATA disk drives and prevent detection of ATAPI Devices by non ATAPI-aware BIOS, ATAPI Devices shall implement the following upon receipt of an ATA SRST: 1. Perform SRST PDIAG sequence see "5.18.2 SRST Initialization Sequence" on page 46. 2. Initialize the task file with Status = 00h or 10h, Error = According to SRST Sequence, Sector Count = 01h, Sector Number = 01h, Cylinder Low = 14h, Cylinder High = EBh and Drive/Head = 00h. Note that Device 0 will be seleted after the completion of the SRST sequence. 3. The functionality of the DRDY and DSC bits shall be restored on the first command following an SRST. 4. Continue executing commands or play operations. 5. Leave Mode settings or Set Feature settings unchanged. 6. If a selected ATAPI Device detects SRST while its own DRQ or BSY is set (1), then the command in progress shall be stopped. DB> А у тебя не завалялось инструкции, как DB> регулировать скорость вращения в DB> CD-ROM'е? 10.8.23 SET CD SPEED Command The SET CD SPEED command provides a means for the Нost to set the spindle speed to be used while reading and writing CD data. Note that the Play commands may not use the speed set by this command. 0 Operation code (BBh) 1 Reserved 2 MSB Read Drive Speed in Kbytes/Second 3 LSB 4 MSB Reserved for Write Drive Speed in Kbytes/Second 5 LSB 6 Reserved 7 Reserved 8 Reserved 9 Reserved 10 Reserved 11 Reserved The Drive Speed parameter contains the requested Data Rate the drive should use. The drive may choose to select the speed specified or any slower rate. A value of FFFFh will set the Drive Speed to the Maximum supported. Requesting a speed faster than the drive supports will not generate an error. The actual maximum speed supported is returned in the Capabilities Mode Sense page (See "10.8.6.4 CD-ROM Capabilities and Mechanical Status Page" on page 115.) Замечания по поводу скорости с сайта insidePro.com: ------------------------------------------ Хакерские секреты, или Рецепты тормозной жидкости для CD Появление высокоскоростных приводов CD- ROM породило огромное количество проблем, и, по общему мнению пользователей, плюсов здесь гораздо меньше,чем минусов.Это реак─ тивный гул, вибрация, разорванные в клочья диски - скажите, на кой черт всё это вам нужно? К тому же,многие из алгоритмов при─ вязки к CD на высоких скоростях чувствуют себя крайне неустойчиво, и защищённый диск запускается далеко не с первого раза, если вообще запускается.Какой же из всего этого выход? Естественно - тормозить! Благо, ко─ манду SET CD SEED (опкод 0BBh) большинство приводов всё-таки поддерживает. Казалось бы,задал нужные параметры и вперёд! Ан нет - тут всё не так просто... Неприятность первая (маленькая, но зато досадная). Скорость задаётся не в "иксах", а в килобайтах в секунду (именно в кило─ байтах, а не байтах!). Причём однократной скорости передачи соответствует пропускная способность в 176 килобайт в секунду. А двукратной? Думаете, 176*2=352? А вот и нет - 353! Зато трёхкратная скорость вычи─ сляется в полном соответствии с привычной нам математикой: 176*3=528, но уже 4-крат─ ная скорость опять отклоняется от "иксов": 176*4=704, против 706 по стандарту. Непра─ вильно заданная скорость приводит к уста─ новке скорости, на ступень меньшей ожидае─ мой, причём соответствие между исками и ступенями далеко не однозначное. Допустим, привод поддерживает следующий ряд скорос─ тей: 16x,24x,32x и 40х. Если заданная ско─ рость (в килобайтах в секунду) не дотяги─ вает до нормативной скорости 32 "икса", то привод переходит на ближайшую "снизу" под─ держиваемую им скорость,т.е.в нашем случае 16х. Отсюда мораль: для перевода "иксов" в килобайты в секунду их нужно умножать не на 176, а на 177! Неприятность вторая (крупнее и досад─ нее). Команды, выдающей полный список под─ держиваемых скоростей,в стандартной специ─ фикации нет,и добывать эту информацию при─ ходится исключительно методом перебора. Корректно работающая программа перед нача─ лом такого перебора должна убедиться в от─ сутствии носителя в приводе, а если он там есть - принудительно открыть лоток. Дело в том, что раскручивание некачественного CD- ROM диска до высоких скоростей может при─ вести к его разрыву и вытекающей отсюда порче самого привода. Пользователь должен быть абсолютно уверен в том, что установ─ ленный в привод диск будет вращаться имен─ но с той скоростью,с которой его просят, и ваша программа не станет самопроизвольно увеличивать скорость без видимых на то причин. Неприятность третья (или тихий ужас). Некоторые приводы (в частности, TEAC 522E) успешно заглатывают команду SET CD SPEED и подтверждают факт изменения скорости, воз─ вращая в MODE SENSE её новое значение, од─ нако физически скорость диска остаётся не─ изменной вплоть до тех пор, пока к нему не произойдёт того или иного обращения. Поэ─ тому вслед за SET CD SPEED недурно бы дать команду чтения сектора с диска, если,коне─ чно, диск вообще присутствует. Изменять же скорость привода без диска в лотке - сове─ ршенно бессмысленная операция, пригодная разве что для построения ряда поддерживае─ мых скоростей,т.к.после вставки нового ди─ ска в привод прежние скоростные установки оказываются недействительными, и наиболее оптимальная (с точки зрения привода!) ско─ рость для каждого диска определяется инди─ видуально. Также привод вправе изменять скорость диска по своему усмотрению, пони─ жая её, если чтение идет неважно, и, соот─ ветственно, увеличивая обороты, если всё идёт хорошо. ------------------------------------------ Последний абзац - чистая правда, сам с этим мучаюсь. Budder: Определение HDD (Master) и CDD (Slave): ------------------------------------------ DETECT CALL SEL_MAS CALL DRDET LD A,D:OR E:LD A,0:JR NZ,ENDC INC A ENDC LD (HDEN),A CALL SEL_SLA LD A,#08:CALL COMM LD A,1,(CDEN),A CALL CDDET:RET Z NoCD LD A,201,(PTCD),A XOR A:LD (CDEN),A RET CDEN NOP ;1-устройство есть, HDEN NOP ;0-устройство отсутствует ------------------------------------------ Hа выходе результат будет в CDEN и HDEN! ------------------------------------------ COMM LD BC,#F0:OUT A:RET XPOZI LD (LTHL),HL,(LTDE),DE ;LBA on! LD A,H,H,D,D,E,E,A ;DE,cyl H,head L,sec POZI LD A,H:AND %00001111:LD H,A LD A,(DRVRE) OR H LD BC,#D0:OUT A LD A,L,C,#70:OUT A LD A,D,C,#B0:OUT A LD A,E,C,#90:OUT A RET RPOZ LD BC,#D0:IN A:AND #0F LD H,A,C,#70:IN A LD L,A,C,#B0:IN A LD D,A,C,#90:IN A LD E,A RET ;----------------------------------------- CDDET CALL SEL_SLA DRDET LD DE,0 LD H,D,L,E CALL XPOZI LD A,#EC CALL COMM .3 HALT ;задержка в 3/50 сек, ;дающая IDE устройству CALL RPOZ ;время подумать, а LD HL,#EB14 ;есть ли оно? ;) OR A:SBC HL,DE RET Z NFOC LD A,1:OR A RET ;----------------------------------------- SEL_SLA LD A,#B0 LD (DRVRE),A LD BC,#D0:OUT A:LD C,#F0:IN A RLCA RET SEL_MAS LD A,#E0 JR SEL_SLA+2 ;----------------------------------------- DRVRE NOP LTHL DS 2 LTDE DS 2 ------------------------------------------ Процедуры ожидания BSY: ------------------------------------------ RDY LD BC,#F0:IN A ;бесконечное RLCA:RET NC ;ожидание BSY JR RDY READY LD E,0,D,0 ;ожидание BSY LD BC,#F0:IN A ;с тайм-аутом RLCA:JR C,RY XOR A:OUT (254),A:RET RY LD BC,#F0,BC,#F0 ;холостой ход DEC D:JR NZ,READY+4 DEC E:JR NZ,READY+2 LD A,1:OUT (254),A CALL ECCOM EI:HALT JR READY ECCOM NOP:LD BC,#F0,A,#EC:OUT A:RET ;при работе с HDD в ECCOM нужно занести ;значение 201 (RET), а при работе с CDD ;занести 0 (NOP) В нынешнем движке WDC вместо READY сто─ ит READY2: ------------------------------------------ READY2 XOR A:LD (TMR),A ;ожидание BSY REA LD BC,#F0:IN A ;с тайм-аутом RLCA:JR NC,RY2 ;в 1/2 секунды LD A,(TMR):CP 25:JR C,REA LD A,1:OUT (254),A CALL ECCOM EI:HALT JR READY2 RY2 XOR A:OUT (254),A RET TMR NOP I_N_T PUSH HL ;должно висеть LD HL,TMR:INC (HL) ;на прерываниях POP HL EI RET ------------------------------------------ Hо таковой требует присутствия счётчика на прерываниях... Hа самом деле READY нужно вызывать ТОЛЬКО перед выполнением новой команды, а в некоторых случаях, где таковое принципи─ ально, вызывать после команды обычный RDY (или не вызывать ни тот, ни другой). Пример: CALL READY ;ожидание/ ;задание готовности CALL EJECT ;передача пакета ;на выдвиг трея CALL RDY ;ожидание исполнения Ещё одно важное место - это ожидание DRQ перед приёмом данных в процедуре чте─ ния сектора: ------------------------------------------ ;процедура чтения сектора ;HL=куды остальное в пакете сидит READSE LD (HLAD),HL RETRYL XOR A:OUT (254),A CALL READY LD HL,READP:CALL SNDPAK ;отдаём команду LOADSE1 LD A,5:OUT (254),A ;чтения сектора CALL READY CALL ERROR_7:JR C,RETRYL LD D,0 ;на некоторых особо глючных CD-приводах ;здесь может повиснуть,если сделать просто ;вызов WAITDRQ WDQ LD BC,#F0:IN A BIT 3,A:JR NZ,WQR DEC D:JR Z,RETRYL JR WDQ WQR LD HL,(HLAD) GSLOD .4 CALL READS XOR A:OUT (254),A RET HLAD DS 2 READS LD C,#10,D,#80 RE1 INI:INC C INI:DEC C INI:INC C INI:DEC C DEC D:JR NZ,RE1 RET ;----------------------------------------- SNDPAK PUSH HL ;IN HL ADDR OF PAK CALL READY CALL SEL_SLA LD HL,#0800 CALL OUTRCIL ;выставляем значения ;счётчика байтов LD A,#A0 ;даём комаду о LD BC,#F0:OUT A ;передаче пакета POP HL LD BC,12 TRANSOU PUSH BC CALL RDY CALL WAITDRQ POP BC OR A RR B,C JR NC,$+3 INC BC TOUT1 PUSH BC INC HL LD A,(HL),BC,#11 OUT A DEC HL LD A,(HL):DEC C OUT A INC HL,HL POP BC DEC BC LD A,B OR C JR NZ,TOUT1 RET OUTRCIL LD A,L,BC,#90:OUT A LD A,H,C,#B0:OUT A RET ;-------------чтение пакета--------------- ERRT POP BC RET TRANSIN ;HL=куды BC=скока PUSH BC CALL SEL_SLA CALL RDY,ERROR_7:JR C,ERRT CALL WAITDRQ POP BC OR A RR B,C JR NC,$+3 INC BC T_I1 IN A,(#10):LD (HL),A:INC HL IN A,(#11):LD (HL),A:INC HL DEC BC LD A,B:OR C JR NZ,T_I1 RET HLTOLEN LD BC,#90,A,L:OUT A LD BC,#B0,A,H:OUT A RET LENTOHL LD BC,#90:IN A:LD L,A LD BC,#B0:IN A:LD H,A RET WAITDRQ LD BC,#F0:IN A BIT 3,A:RET NZ JR WAITDRQ ERROR_7 LD BC,#F0:IN A RRCA RET ------------------------------------------ Во всех остальных процедурах можно вы─ зывать просто WAITDRQ! (Где таковое требу─ ется.) Ожидание CD привода в любой момент вре─ мени: подробно описать не могу, т.к.многие мелочи уже не помню. Скажу только,что в те самые моменты, когда диск не готов,CD при─ вод воспринимает любую команду как ошибку (за искл. некоторых).Сигнал BSY индицирует о занятости, как минимум после подачи ка─ кой-либо команды (к примеру,передача паке─ та), но если не было ошибки! После передачи пакета независимо от то─ го, был ли он передан, ставится процедура READY (смотрим процедуру чтения сектора), за ней проверка сигнала ошибки в регистре состояния. Если ошибка,то повторяем подачу пакета, таким образом и ожидается готов─ ность CD привода в любой момент вренени... В моём двиге есть ещё одна особенность: контроль таймаутов,кот. обязательно должны быть в процедуре ожидания BSY (во всех драйверах на PC так делается),я выбрал 1/2 секунды. Hа PC ограничение по времени ожи─ дания стоит не только на BSY,но и на оста─ льные сигналы.При таймауте у меня в движке подаётся команда #EC, кот. является обяза─ тельной для всех ATAPI устройств,и которая отвешивает BSY! (Если не нравится #EC, то можно использовать #00,но для таковой надо ещё указывать код субкоманды в FR (регистр свойств), в нашем случае он=0.) SMT: Ещё немного поигрался с прямым доступом к CD-ROM и понял, откуда растут ноги у по─ дачи пакета с кодом #00. Часто первая по─ данная на CD-ROM команда выполняется с ошибкой. Но нужно смотреть,что за ошибка,а не пытаться повторить или дать другую ко─ манду. Скорее всего, в регистре ошибок ус─ тановлены MC [???] или MCR [Media Change Requested в ATAPI - D3 регистра ошибок] , т.е. юзер нажимал eject или вставил новый диск. В этом случае привод оповещает хост отбрасыванием следующей команды с соотв. ошибкой.A вместо того,чтобы посылать пакет #00, который "проглотит" это оповещение, нужно повторить операцию, если ошибка из разряда MC/MCR. Ведь вполне возможно (хотя очень маловероятно),что смена носителя или нажатие eject придётся как раз между кома─ ндами #00 и рабочей командой,тогда рабочая команда обломается, несмотря на заранее переданный #00. 10.8.26 TEST UNIT READY Command The TEST UNIT READY command provides a means to check if the Device is ready. This is not a request for a self-test. If the Device would accept an appropriate medium-access command without returning CHECK CONDITION sta-tus, this command shall return a GOOD status. If the Device cannot become operational or is in a state such that an Host Computer action (e.g. START/STOP UNIT command with LoEj = 0 & Start = 1) is required to make the unit ready, the ATAPI CD-ROM Drive shall return CHECK CONDITION status with a sense key of NOT READY. 10.8.26.1 Using the TEST UNIT READY Command The TEST UNIT READY command is useful in that it allows a Host Computer to poll a Device until it is ready without the need to allocate space for returned data. It is especially useful to check cartridge status. ATAPI CD-ROM Drives are expected to respond promptly to indicate the current status of the device. 0 Operation code (00h) 1 Reserved 2 Reserved 3 Reserved 4 Reserved 5 Reserved 6 Reserved 7 Reserved 8 Reserved 9 Reserved 10 Reserved 11 Reserved P.S. И тогда становится понятно, почему в твоём случае пакет #00 требовался только один раз - ты просто диск не менял. DB> 1. Когда я формирую сброс через управ─ DB> ляющий регистр (#0C, потом через неко─ DB> торое время #08), то как определить, DB> когда мне дать #08? Имхо должен быть DB> какой-то сигнал об этом? Снятие BSY. Он моментально устанавливается после подачи #08. Сброс через ATA SRST не прерывает кома─ нду ATAPI, лишь выставляет сигнатуру в ре─ гистре цилиндра. Впрочем, он не мешает. DB> 2. Если запустить инициализацию до то─ DB> го, как сидюк после аппаратного сброса DB> (RES на шлейфе) успевает раскрутиться, DB> то CD-ROM игнорирует команды. Как я ни DB> читал регистры статуса и ошибки, но DB> разницы между двумя состояниями (успел DB> /не успел раскрутиться) не заметил. Ошибки читаются командой REQUEST SENSE (#03). DB> 3. Hекоторые приводы дают ошибку на DB> команду установки скорости, после чего DB> перестают реагировать на команды. Как DB> заставить их работать после этого? Не давать команду. Про поддержку спросить через MODE SENSE / CAPABILITIES. Ред.: Там нет признака,что привод умеет менять скорость! DB> 4. Как узнать, что пришло время снова DB> подать команду установки скорости DB> (т.е. как узнать, что привод её само─ DB> произвольно изменил)? а. Считать текущую скорость через MODE SENSE / CAPABILITIES (#5A с параметром #2A). б. Обычно скорость сбрасывается при смене носителя. Ставить флажок после обработки MCR; если флаг установлен, перед командой задать заново скорость (для простоты можно предварить чтение каталога SET CD SPEED. Раз диск сменился, пользователь вынужден перечитать, заодно скорость установится).
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября