(Также здесь будут описаны ошибки, которые я допустил, пытаясь сделать этот эмулятор, может, кого-то это убережет, от необдуманных поступков)
Итак у нас есть PS1 с платой SCPH-5502, DE1 с CycloneII на борту, клон DSLogic Plus и большое желание проэмулировать CDRom.
3. Что такое TOC где он живет и как выглядит?
3.1 Смотрим логическим анализатором
Для начала я запустил анализатор, подключил его к основным исследуемым пинам. Стартанул захват и нажал кнопку, которая отвечала за закрытия крышки приставки. Эксперименты проводил на двух играх Forsaken и G-Police 2. Первая выбрана потому, что у неё должен быть большой TOC, так как у игры много аудио треков сопровождения. А вторая, потому что была под рукой. Полученные дампы можно посмотреть скачать здесь(Forsaken, G-Police 2) при помощи программы DSView. При беглом взгляде стало понятно, что надо искать информацию о том, как всё-таки хранится TOC.
(Нога SCOR снята криво, как оказалось у меня убит 7 канал на логическом анализаторе, но в момент, когда я с снимал, эти дампы я этого не знал)
3.2 Так что же такое TOC?
Ноги у CD-Data растут из CD-Audio. А на последних хранились аудио треки, их было несколько и чтобы бытовому плееру узнать, сколько их именно и какую длину они имеют, придумали TOC. TOC расшифровывается как Table of content, что можно перевести как оглавление. Так вот на CD-Audio было два потока данных: основной с аудиоданными, и субканальные данные. В аудиоданных были закодирован аудио поток в формате 16 бит, 44100 герц без компрессии(ну на самом деле туда ещё можно запихнуть DTS/AC3 но это уже совсем другая история). В субканальных данных была информация необходимая для сервисных нужд плеера, номер трека, текущее время воспроизведения трека диска. А также может быть куча дополнительной информации, в виде всяких CD-Text, регистрационных номеров диска в разных базах итд. Субканал сам подразделяется на восемь подканалов, именуемых буквами от P до W. В общем, хранить TOC в аудиоданных было не вариант, так как зачастую они напрямую шли на ЦАП и никак не анализировались. Поэтому данные решили хранить в субканале(он же субкод/subcode). Те, кому доводилось записывать компакт диски должны помнить, что привод в начале диска пишет загадочный Lead-In потом данные и потом Lead-Out. Так вот Lead-In как раз и содержит данные TOC. Который закодированы в Q канале.
3.3 Формат Q субканала
Не углубляясь в то, как устроено хранение данных на диске, нам пока достаточно знать следующее. Сектор на диске содержит 2352 байта(ну как таковой понятие сектор оно и не совсем верное). На каждый сектор приходится один блок субканальных данных. Каждый субканал несет 96 бит информации. Нас сейчас интересует только Q подканал.
Формат данных этого подканала достаточно прост.
Control | Mode-Q(ADR) | Data-Q | CRC |
4-Bit | 4-Bit | 72-Bit | 16-Bit |
Поле Control содержит тип текущего трека, аудио/дата, сколько каналов, есть ли предискажение, запрещено ли его копировать.
00x0b | 2 audio channels without pre-emphasis |
00x1b | 2 audio channels with pre-emphasis of 50/15 µs |
10x0b | 4 audio channels without pre-emphasis |
10x1b | 4 audio channels with pre-emphasis of 50/15 µs |
01x0b | Data track, recorded uninterrupted |
01x1b | Data track, recorded increment |
11xxb | reserved |
xx0xb | digital copy prohibited |
xx1xb | digital copy permitted |
Для нас интересны два варианта это 0x4 — дата трек, и 0x0 — аудио трек 2 канала.
Поле Mode-Q оно же ADR указывает, что дальше закодировано в Q канале. Нас интересует только
значение 0x1, которое отвечает за указание текущей позиции на диске. Также ещё есть вариант 0x2, который отвечает за Media Catalog Number и 0x3, отвечающий за ISRC. Но они нам на данный момент не нужны.
Формат Mode-Q 0x1 имеет следующий вид:
TRACK | INDEX | MIN | SEC | FRAME | ZERO | AMIN | ASEC | AFRAME |
8-Bit | 8-Bit | 8-Bit | 8-Bit | 8-Bit | 8-Bit | 8-Bit | 8-Bit | 8-Bit |
Где Track — номер текущего трека, для трека Lead-Out значение фиксировано 0xAA. Index по сути используется два варианта это 0 пауза «перед началом» трека, и 1 сам трек. По идее задумывалось, чтобы один трек можно было разбивать на дополнительные части, но видимо оказалось ненужным, либо его добавили из за особенности работы CIRC но сейчас не об этом.
MIN/SEC/FRAME относительное положение головки на диске, MIN может быть от 00 до 99, SEC от 00 до 59. FRAME от 00 до 74(адресация на CD дисках называется MSF как раз из-за этих параметров). Это значение описывает положение головки относительно начала текущего трека. Поля AMIN/ASEC/AFRAME описывают абсолютное положение головки от начала зоны дынных на диске. Зона данных идёт сразу за зоной Lead-In, и как бы это не было странно трек Lead-Out включен в зону данных. Диапазон значений такой же, как и у MIN/SEC/FRAME. Важный момент MIN/SEC/FRAME во время когда INDEX равен 0 идут на уменьшения значений, а при INDEX равный 1 на увеличение. Поля AMIN/ASEC/AFRAME всегда идут строго на увлечение. Поле ZERO всегда равно 0x00
Однако в зоне Lead-In поля имеют немного другие значения, а именно: MIN/SEC/FRAME и ZERO работают также как и везде. Поле TRACK равно 0x00, что в целом логично. Однако поле INDEX и
AMIN/ASEC/AFRAME отданы под описание трека и его параметров. INDEX указывает номер трека описываемого в TOC, а поля AMIN/ASEC/AFRAME его позицию, выраженную абсолютном времени на диске. Как же есть специальные значения выражено в виде INDEX с параметром 0xA0, 0xA1, 0xA2:
Index | AMIN | ASEC | AFRAME |
0xA0 | Номер первого трека на диске обычно(всегда) 0x01 | Тип трека: 0x00 — CD-DA or CD-ROM 0x10 — CD-I 0x20 — CD-ROM-XA |
0x00 |
0xA1 | Номер последнего трека | 0x00 | 0x00 |
0xA2 | AMIN начала Lead-Out | ASEC начала Lead-Out | AFRAME начала Lead-Out |
Вот из этих записей и состоит TOC. Длинна же самого Lead-In, должна быть около 4500 секторов. В которых эти данные повторяются, что скорей всего сделано для надежности. Как строит TOC приставка, я точно не знаю. Но алгоритм должен быть достаточно прост, что-то похожее на следующее. Позиционируемся на Lead-In зная, что у него Track = 0x00. И начинаем заполнять адреса начала всех треков, используя данные из Q субканала, Само количество треков мы узнаем из служебной записи 0xA1. Когда все записи заполнены, считаем, что TOC прочитан.
По тестам с разными дисками стало понятно, что TOC на штамповке и на самописных болванках немного отличается. Например, относительно время в Lead-In на штамповке шло от 00:00:00 и просто по нарастающей. А на записанной болванке оно начиналось явно не с нулевой метки, и было рассчитано, так, что бы последний сектор Lead-in приходился на значение 99:59:74 то есть максимально возможное время в адресации MSF. Что, на мой взгляд, более верное решение, но приставке, да и другим приводам абсолютно безразличен этот факт.
3.4 Просто всякие мелочи
Lead-In это единственная область, в которой свои отметки времени не связаны с основной областью данных. Также трек Lead-In по сути является треком номер 0. Все остальные треки, включая трек Lead-Out, содержат две отметки времени время от начала области данных, и время от начала текущего трека. Данные всех треков закодированы в формате BCD, кроме номера трека Lead-Out он имеет значение 0xAA. Lead-Out служит для указания того что это конец диска (всякие мультисессии мы не рассматриваем), и дальше никаких данных не будет. CXD2545 умеет читать их все, но в PS1 он подключен, так что может читать только канал Q, да ещё и настроена, так что в последних двух байтах выдается не CRC, а PeakMeter.
4 Первые попытки эмуляции TOC
4.1 Размышления
(В статье описаны события 4-5 летней давности, поэтому могут быть неточности, прошу с понимание отнестись к этому)
Формат данных TOC известен, как он строится тоже ясно. Пришло время обдумать, как это всё эмулировать. У нас есть плата с Cyclone II но читать карту на Verilog и обрабатывать команды привода задача не очень веселая. Поэтому было принято решение собрать систему с «софт» процессором NiosII, к которому сделать свой модуль, который бы эмулировал тот самый CXD2545 и подключался к процессору как устройство мапированное на память. Учитывая, что автор не FPGA разработчик, неплохой такой план.
Что же для этого требуется:
- Сделать входную шину CLOK/DATA/XLAT которая по приходу XLAT дергает прерывание и дает прочитать, что от нас хочет приставка
- Сделать шину чтения субканала SQCK/SUBQ/SCOR по которой мы будем отправлять приставке данные
Саму шину данных делать пока не нужно, там при чтении TOC ничего нужного нет.
4.2 Первые наброски
В SOPC Builder(графический интерфейс, для генерации процессорных системы в Quartus) бала создана система. Которая состояла из:
Nios II процессора, On-Chip памяти, UART модуль для отладки и таймера.
Убедившись, что система собирается, и потом, убедившись, что Nios II стартует как надо, и можно писать и отлаживать программы, я решил, что пришла пора написать первый компонент системы.
Он должен будет читать с данные с шины управления CXD2545, и передавать их в процессор.
Модуль я назвал CXD2545_CPU. Я решил, что для этой шины, нужно, что-то похожее на сдвиговый регистр, куда задвигаются команды, по сигналу XLAT регистр должен был копироваться в другой регистр, и дергать прерывание, чтобы процессор знал, что пришла команда от приставки. И посидев немного в мастере создания компонентов SOPC, была получена заготовка для модуля, из которой, я как смог слепил первый модуль. (Автор не FPGA разработчик, поэтому его Verilog код может нанести травму FPGA разработчикам, за что он сразу извиняется.)
module CXD2545_CPU (
input wire clk, // clock.clk
input wire rst_n, // .reset
input wire [3:0] m_addr, // avalon_slave.address
output wire [31:0] m_read_data, // .readdata
input wire [31:0] m_write_data,// .writedata
input wire m_read, // .read_n
input wire m_write, // .write_n
output wire m_irq, // interrupt_sender.irq_n
input wire CLOK, // cxd_cpu.export
input wire DATA, // .export
input wire XLAT // .export
);
reg [23:0] cxd_cmd;
reg [23:0] cxd_cur_cmd;
reg reg_cur_clok;
reg reg_prev_clok;
reg reg_data_cur;
reg reg_cur_xlat;
reg reg_prev_xlat;
reg irq;
assign m_read_data[23:0] = cxd_cmd;
assign m_irq = irq;
always @(posedge clk) begin
if(rst_n == 1) begin
irq <= 1'b1;
end else begin
reg_prev_clok <= reg_cur_clok;
reg_cur_clok <= CLOK;
reg_prev_xlat <= reg_cur_xlat;
reg_cur_xlat <= XLAT;
reg_data_cur <= DATA;
if((reg_prev_clok ==1'b0) && (reg_cur_clok ==1'b1)) begin
cxd_cur_cmd[23:0] <= {reg_data_cur, cxd_cur_cmd[23:1]};
end
if((reg_prev_xlat ==1'b1) && (reg_cur_xlat ==1'b0)) begin
cxd_cmd <= cxd_cur_cmd;
irq <= 1'b0;
end
if((m_read == 1'b0) && (m_addr == 4'h1)) begin
irq <= 1'b1;
end
end
end
endmodule
Надо заметить это единственный модуль, который дожил до рабочей версии эмулятора и только он и сохранился из первой версии проекта. Но разберем его по порядку. У нас есть две группы сигналов, одна относится к шине Avalon-MM, с которой работает Nios II и вся его периферия. И ужа знакомая нам шина команд CXD2545. А также сигнал сброса системы, и сигнал тактировая системы. Вдаваться в работу всей шины Avalon-MM мне не хочется, кому интересно, думаю смогут найти её принципы работы сами. Поэтому вкратце опишу что делается в модуле (всё что описано ниже происходит по положительно фронту клока):
if(rst_n == 1) begin
irq <= 1'b1;
end else begin
Если пришёл сигнал сброса мы убираем сигнал прерывания(активный уровень сигнала прерывания у нас 0). Если ресета не было:
reg_prev_clok <= reg_cur_clok;
reg_cur_clok <= CLOK;
reg_prev_xlat <= reg_cur_xlat;
reg_cur_xlat <= XLAT;
reg_data_cur <= DATA;
Запоминаем текущее значения пришедших сигналов в регистрах, а их старые значения CLOK/XLAT запоминаем в регистрах предыдущих значений.
if((reg_prev_clok ==1'b0) && (reg_cur_clok ==1'b1)) begin
cxd_cur_cmd[23:0] <= {reg_data_cur, cxd_cur_cmd[23:1]};
end
Если прошлое значение clok было 0 а текущее стало 1(поймали фронт сигнала), задвигаем в регистр текущее значение линии DATA.
if((reg_prev_xlat == 1'b1) && (reg_cur_xlat == 1'b0)) begin
cxd_cmd <= cxd_cur_cmd;
irq <= 1'b0;
end
Если XLAT перешел из состояния 1 в 0 то переносим текущее значение сдвигового регистра, в регистр где хранится текущая команда и ставим запрос на прерывание.
if((m_read == 1'b0) && (m_addr == 4'h1)) begin
irq <= 1'b1;
end
При чтении значения из адреса 0x4 относительно базового адреса модуля, сбрасываем запрос прерывания.
assign m_read_data[23:0] = cxd_cmd;
assign m_irq = irq;
Отображаем на шину данных Avalon-MM постоянно(независимо от запрошенного адреса) значения регистра cxd_cmd а на сигнал прерывания регистр irq. Для тех кто незнаком с Verilog следует уточнить, что в отличии от обычных программ, результатом компиляция программы на Verilog получает схема. И все конструкции которые описаны, выполняются одновременно. А система переходит из одного состояния в другое по событиям описанным в блоках always. И не смотря на то, что
reg_prev_clok <= reg_cur_clok;
Написано выше чем условие где это самый reg_prev_clok сравнивается с чем то. На момент сравнения он будет иметь значение которое имел когда мы вошли(если смотреть по тексту) в блок always, и поменяет его уже когда весь блок будет отработан. По началу обычным программистам это очень выносит
После того как удалось это написать, я подключил DE1 параллельно чипу CXD2545. Набросал простую программу на Си под Nios II. И попробовал на приставке нажать кнопку, которая отвечает за мониторинг закрытия крышки. В консоль весело посыпались команды отдаваемые приставкой, приводу. Это была первая маленькая победа. И одна подняла энтузиазм до небывалых значений. Теперь надо было разобраться с командами, которые шли контроллеру и понять, как их эмулировать.
5. Команды CXD2545
Список команд достаточно небольшой, хотя если рассматривать их вместе с параметрами, то он огромен, но не все так страшно. За номер команды отвечает, первые 4 бита, остальное это параметры команды. Вот перечень команд с их описание:
Код | Название блока команд | Описание |
0x0 | Focus Control | Команды управления фокусом, включить/выключить, и параметры фокуса, для эмуляции не очень и нужны. |
0x1 | Tracking Control | Команды управления трекингом, включить/выключить, и параметры антишока, тормоза и прочее, для эмуляции тоже не нужны. |
0x2 | Tracking Mode | Прямое управление линзой трекинга, включение выключение приводов салазок, и магнитного привода линзы, возможность двигать вперед/назад эти приводы, явно нужно будет эмулировать. |
0x3 | Select | Огромный блок с кучей под блоков, в которых прописываются всякие тонкие настройки работы механики, усилителей и прочего, как оказалось для эмуляции не нужен, но первый взгляд на него очень сильно меня напугал. |
0x4 | Auto sequence | Команды перехода по трекам, вперед или назад на 1/10/2N/M трек, но это не те треки которыми нумеруются аудиозаписи на диски, а дорожки спирали, на которой и записана вся информация на диске, обязательно для эмуляции. |
0x5 | Blind (A, E),Brake (B),Overflow (C, D) | Тайминги разных фаз работы механики, для эмуляции не нужны. |
0x6 | Sled kick, brake (D),Kick (F) | Ещё тайминги разных фаз работы механики, для эмуляции не нужны. |
0x7 | Auto sequence track jump count setting | Число треков на которое надо прыгать для команды 0x4 при указании параметров 2N или M треков, для эмуляции нужна. |
0x8 | MODE specification | Разные параметры работы CDRom, в принципе оказалось эмулировать не обязательно |
0x9 | Function specification | Разные параметры работы CDRom, для эмуляции важен только флаг DSPB указывающий на какой скорости сейчас должен работать привод 1X или 2X |
0xA | Audio CTRL | Параметры отвечающие за роботу привода в режиме Audio, по логам выходило что приставка устанавливает его один раз и больше не трогает, значит и эмулировать не надо. |
0xB | Traverse monitor counter setting | Счетчик треков, который дергает ногу COUT при перемещении головки при помощи команд 0x2. Изначально я не понял его назначения, это стоило наверно 3х дней отладки. |
0xС | Spindle servo coefficient setting | Параметры для работы механики, для эмуляции не нужны. |
0xD | CLV CTRL | Параметры для работы механики, для эмуляции не нужны. |
0xE | CLV mode | Управление шпинделем, раскрутка, тормоз, режим работы. Когда шпиндель крутится нужно выдавать данные субканала и основного канала, нужная команд |
В общем как оказалось команд необходимых для эмуляции не так много и в целом они достаточно простые. Ну а раз так то пишем дальше.
6. Начинаем эмулировать
6.1 Первая попытка эмуляции
Так как проект почти все время находился в состоянии, ну зачем тут система контроля версий, ничего ещё не написано, то дальнейшее я описываю по памяти. В общем, я набросал код модуля, которые отвечал за вывод субканала, это было три 32х регистра, и вывод их через сдвиговый регистр. SCOR сигнал эмулировался при помощи, добавленного модуля PIO которые есть в базовой поставке ядер от Altera. Работало все просто после получение команды 0xE с параметром включить включения шпинделя, я по таймеру начинал бросать 75 раз в секунду, данные субканала. Сами данные я захардкодил, только параметры MSF рассчитывал на лету. Команды 0x4 и 0x2 эмулировались крайне слабо. И у меня зачесались руки проверить, как это работает. А для этого надо было отключить чип CXD2545. Глядя на схему из книжки, я решил отпаять L711, чтобы обесточить чип. После чего подключился к ногам CLOK/DATA/XLAT и SQCK/SUBQ/SCOR ну GND.
Первое включение показало что, CXD2545 видимо натягивает через другие ноги питания, и время от времени гадит на шину. После чего я не придумал ничего лучшего, чем отпаять это чип нафиг. Но на всякий перед этим снял ещё пачку всяких событий анализатором, старт с разных треков, попытка загрузки игр(хотя дальше черного экрана с логотипом PS оно уже не могло идти). Это как потом выяснится, это очень мне помогло. В итоге принес с работы 702 Lukey и феном снял этот чип. Загрузил прошивку в FPGA, стартанул программу Nios II. Включаю приставку, иииии… черный экран, ресет, ещё ресет, ничего. Обидно.
6.2 Поиск проблем
Первое что пришло в голову это то, что CXD2545 генерирует сигналы CDBCLK и CDLRCK, независимо от того идут данные или нет. Может их не хватает, подумал я, и при помощи PLL сгенерировал нужную частоту для CDBCLK и уже из неё получил CDLRCK. Подключил сразу всю шину данных CD. Включаю приставку, слышу заветный звук включения, но на первом логотипе, тот который на белом фоне всё виснет. И никаких команд приставка приводу не шлёт. Энтузиазм начинает падать. Но делать нечего начинаю более детально изучать, как всё работает.
6.3 Примерная схема работы привода CDRom
Посмотрев доступные источники родилась такая схема:
Через чип CXD1815 приставка общается с SUB-CPU, который управляет уже нашим чипом CXD2545. Который в свою очередь шлёт данные с сидирома назад в CXD1815, а уже именно он занимается тем, что либо декодирует данные как сектора в режиме дата, и позволяет их забрать приставке. Либо если это аудиоданные шлёт их в звуковой чип приставке. Также CXD2545 шлёт данные субканала и ещё пару служебных сигналов в SUB-CPU, который её и контролирует. Но ещё более интересный момент был дальше, оказалось, SUB-CPU тактируется от CXD2545. И когда я её убрал, команды посылать он уже не мог. По схеме из книги это должно подключаться так:
А что у нас за нога C16M:
Ну почти 17 мегагерц да еще меняющиеся. Ну да ладно, что делать, подаю 17 мегагерц на этот пин. Ииии опять ничего. Но тут глаз зацепился за то, что почему-то в книжке ноги 67 и 68 замкнуты между собой. А по даташиту это выход частот, с разными делителями. А если посмотреть дальше то нога 64 отвечает за, то на какой частоте работает сам чип. Но по схеме из книге она висит в воздухе. Пришлось немного по изучать плату, чтобы понять, что нога 64 подключена к земле, что указывает на то, что микросхема работает от 16.9344MHz. А нога тактирования SUB-CPU подключена к пину 68, а не 69 и там должно быть около 4 мегагерц. Подав нужную частоту на SUP-CPU и включив приставку, я наконец увидел главный экран с выбором менеджера карточек и CDPlayer'а. Вот такие веселости может преподнести литература.
Запустил программу, нажал кнопку закрытия крышки, и поучил кучу команд 0x2 с пожеланием двинуть каретку влево. Но тут я быстро догадался, что она ждёт появления сигнала о том, что каретка уперлось в датчик нулевого положения. И по быстрому добавил этот сигнал. После этого ещё пришлось подтянуть SENS к высокому уровню, иначе приставка давала команду фокусировки, но дальше ничего не делала. Итак, не с первого раза, но достаточно быстро TOC считался и отобразился в сидиплеере. Это была первая значимая победа.
6.4 Эмулируем данные CDRom
И тут меня понесло. В систему был добавлен модуль SPI, через который я подключил SD карту. Работать с файловой системой мне не хотелось. Поэтому решил работать с RAW данными с карты. Написал подобие драйвера карты. При этом пришлось править алтеровский SPI драйвер, чтобы он держал ноги SPI в нужном состоянии. После этого я решил, надо разбить данные так, чтобы было удобно с ними работать со стороны Nios II.
Идея была такова, я делаю Dual Clock FIFO, со стороны Nios II я туда засовываю данные, а приставка их со своей стороны забирает. При этом как-то хотелось, ещё синхронизировать субканальные данные. В итоге родилась простая идея на один сектор, который у нас занимает 2352 байта, приходится 12 байт данных, делим 2352 на 12 и получаем что каждые 196 байт, на нужно вставлять 1 байт субканальных данных. Которые я бы пихал в другой сдвиговый регистр, а потом в конце сектора дергаю SCOR. Дальше мысль была проста, даем карте команду read multiple и спокойно тянем из SPI байты и бросаем их в FIFO, а каждый 197 байт в другое FIFO. Карта у нас на двадцати пяти мегагерцах работает, данные идут всего на двух(ну и на четырех на 2х скорости). Да ещё и FIFO есть, времени вагон, должно заработать.
6.5 Работает но криво
После долгих мытарств с Verilog и отладкой этой вроде простой задачи, оно таки заработало, аудио треки воспроизводились. Но с хрустом каким-то. Джитер PLL, подумал Штирлиц. И стал искать генератор на нужную частоту. И в каком-то из кучи древних сидиромов нашел, кажется на 33,86. Правда, это был вроде бы кварц, и пришлось делать обвязку. Но после подключения внешнего клока, проблема почти свелась к нулю, но только почти. В итоге я взял клоковый сигнал, который приходил на CXD2545 изначально. И это решило проблему на 99,9%, но время от времени, все равно были слышны щелчки. Ну, да и фиг сними. Пришло время загрузить игру. Учитывая все особенности диска, всякие прегапы постагапы, и прочее, был сгенерирован образ, которые я закинул на карту. Зажал кнопку крышки, и ничего, чуда не случилось.
6.6 Грузим игру(нет)
Стал изучать дампы которые снимал в момент запуска игр. Пришлось даже написать кучу вспомогательных утилит. И тогда всё стало ясно.
С диска данные читались вот в таком формате:
FF 00 FF FF FF FF FF FF FF FF 00 FF 80 01 62 07
Это выглядит очень неправильно. Потому, что data сектор на диске имеет заголовок:
SycnPattern | MSF | MODE | DATA |
12-byte | 3-byte | 1 byte | 2,336 |
00 FF FF FF FF FF FF FF FF FF FF 00 | MM:SS:FF | 1/2 | DATA |
По сути, запись данных на диск ничем не отличается от записи аудио. Отличие есть только в данных субканала где указано что это тип трека Data. А учитывая, что на самом деле субканал по определенным причинам не связан жестко с данными, и может быть получен и в середине(или вообще на другом секторе) дата сектора, что для аудио значения особого не имеет. А вот для данных такое получение номера сектора неприемлемо. Поэтому был введен специальный формат сектора. И привод как раз по синхропоследовательности понимает, что именно сейчас начинается сектор, а по первым 3 байтам узнаёт какой именно сектор.
То есть в данных привода младший и старший байт поменяны местами, и должны идти так:
00 FF FF FF FF FF FF FF FF FF FF 00 01 80 07 62
Это больше походе на правду. Но:
SycnPattern | MSF | MODE | DATA |
00 FF FF FF FF FF FF FF FF FF FF 00 | 01:80:07 | 62 | 2,336 |
в MSF адресации параметр SS не может быть больше 59, а тут 80, да и MODE 62 что тоже не нормально. В целом это могло загнать в тупик но к тому моменту я уже знал, что данные сектора на диске скремблируют, как раз таки чтобы, на диске не встретилась где попало последовательно SycnPattern. И при дескремблировании мы получаем
SycnPattern | MSF | MODE | DATA |
00 FF FF FF FF FF FF FF FF FF FF 00 | 00:00:07 | 02 | 2,336 |
Ну и дальше данные трека тоже были найдены в образе диска. В общем CXD2545 вообще ничего не знает про сектора, она чисто декодирует данные с диска, остальным занимаются чипы которые стоят дальше. Да про всё это срамблирование/дескрамблирование автор узнал из книги «Техника защиты компакт-дисков от копирования» за авторством Криса Касперски. Рекомендую очень просто и понятно всё описано. В итоге, проведя скремблирования секторов в образе, и запустив приставку, секунд через 40-50 я увидел логотип PS на черном фоне. Дальше дело не шло, сколько не жди. Работало это всё не очень то и стабильно. И промаявшись с этим ещё около четырех дней, добавив работу на скорости 2Х на которою приставка переходила при начале загрузки игры. Я понял, что мне надо, более точный дамп лога загрузки игры.
6.7 Точка невозврата
Я был полон энтузиазма. Но у меня не было под рукой нормально паяльника и микроскопа тоже не было, Не было даже лампы настолько для нормального освещения. Но в итоге я решил припаять назад CXD2545 чтобы снять дамп загрузки игры(хотя привод был убит и не особо мог это делать и раньше). В итоге все окончилось очень печально. Я не то закоротил ноги и не смог разглядеть где. Не то содрал дорожки. Потом я нашёл как минимум пару содранных. Но при включении приставки она с дикой скоростью крутила диском. Я повторил пару попыток, окончательно угробив дорожки. Но так и не добился результата. В итоге я отпаял чип, проверил, что хотя бы TOC и аудиотреки читаются. И понял что назад пути нет. Вывод, не надо спешить. Я бы мог спокойно все сделать на работе, где был микроскоп, и нормальный паяльник, и освещение. Но теперь я был в ситуации, когда эмулятор почему-то не работает, по логическому анализатору, я не вижу что не так. И снять данные с рабочего варианта уже не могу. Я ещё пару дней помучился, и забросил это дело. Скорей всего из-за начала роллер сезона, и не желания сидеть ночи на пролет дома.
Конец второй серии
На этом я хочу завершить вторую часть, она и так получилось неприлично большая. Выводы, которые я для себя сделал. Схемам из книг верить можно не всегда. Паять плохим паяльником и без освещения, плохая идея. Спешка даже в момент когда ты переполнен энтузиазма, может его угробить, как и дело, которое ты делаешь.
В третьей части, мы все переделаем, и наконец запустим какую ни будь игру. Также узнаем, наконец, что же скрывалось за ногой SENS, и почему не грузилась ни одна игра.
Автор:
VBKesha