CD video на ZX
О том, как написать плейер видео с ком─
пакт-диска, рассказывает автор того самого
плейера, который был показан на CAFe'2003.
К сожалению,сам плейер не сохранился. Дан─
ным вопросом также занимались PSB и немно─
жко я (Alone Coder). Лично я эксперименти─
ровал только с 16(15)-цветным видео - там
появляются довольно интересные задачи упа─
ковки и т.п.
CD video на ZX
Для звука, естественно, нужно 2 буфера.
Естественно, данные хранятся как
[изображение][звук][изображение][звук] ...
Так как сидюки данные одного сектора
передают очень быстро, то можно не ждать
готовности данных внутри сектора, а только
перед чтением.
У меня сделано так:декрюнчится процеду─
ра чтения одного сектора (2k), в которой,
где надо, расставлен вывод звука (для ка─
чественного звука можно ещё повставлять
NOP'ов или INC HX. У меня ещё само количе─
ство тактов между выводами звука задаётся
как fixed point):
LD C,E : INI
LD C,D : INI
LD C,E : INI
LD C,D : INI
...
[NOP/INC HX]
EXX
OUTI
EXX
LD C,E : INI
LD C,D : INI
LD C,E : INI
LD C,D : INI
...
[NOP/INC HX]
EXX
OUTI
EXX
и.т.д.
Так как надо читать куски не кратные 2k
и не совпадающие с началом сектора (6144 -
экран и 2048 - звук не очень катит:тормоз─
но и весит много), в конце стоит JP на на─
чало, и используется часть и/или процедура
полностью (плавающий RET ).Я это оформил в
виде процедуры, которая читает с текущего
положения в секторе нужное количество байт
и/или секторов. Её можно использовать так:
LD BC,size
LD HL,buff
CALL read
А конкретнее:
LD BC,6912
LD HL,#4000
CALL read
LD BC,1280
LD HL,sndbuf0
CALL read
Ещё, так как надо ожидать готовности
привода и при этом выводить звук, нужна
процедура типа:
w_snd
CALL w_cd
RET Z
NOP ;до фига NOP'ов
EXX
OUTI
EXX
...
JP w_snd
Желательно поставить проверку на окон─
чание буфера (и/или добавить нули после
буфера). Для качества звука желательно эту
процедуру сделать побольше (если количест─
во тактов между выводами звука не целое).
Еще, если будете использовать часть эк─
рана (спрайт) - n знакомест в ширину (на
этом очень много можно сэкономить), надо
сделать таблицу адресов для экранов и для
буферов со звуком и поменять код:
POP HL ;здесь через каждые n байт
;читается новый адрес
LD C,E : INI
LD C,D : INI
...
POP HL ;здесь через каждые n байт
;читается новый адрес
LD C,E : INI
LD C,D : INI
...
[NOP/INC HX]
EXX
OUTI
EXX
Естественно, при таком подходе количес─
тво байт звука на кадр должно быть кратно
n. И ещё, 2048 должно делиться на n без
остатка (хотя если чуть-чуть гемора,то мо─
жно и без этого).
Ред.: Звука должно быть много - с запа─
сом! Дело в том,что где-то раз в 10 секто─
ров ожидание нового сектора затягивается
на жуткий срок - более 20000 тактов.Причём
вне зависимости от скорости (1x/8x/...)!
Причины непонятны.
Общая структура процедуры read такая:
[определяем,сколько и откуда читать]
[вставляем 'RET']
┌─────[JP куда надо]
│
│ ┌──────────────────────────┐
│ │/ │
├────>[посылаем команду CD-ROM'у] │
├────>[ожидаем готовности] │
└────>[читаем] │
│ │
└──────────────────────────┘
Можно пользоваться командой чтения
группы секторов (в смысле, кол-во секторов
задавать >1 ), чтобы не посылать команду
каждый сектор - но далеко не всем приводам
это нравится (мой DVD на это жалуется и
читать отказывается). А с отменой текущей
команды всё вообще очень сложно - если
прервать чтение (RESET,к примеру),то потом
сложно 'достучаться' до привода - сложно
понять, сколько нулевых команд ему надо.
Hedgehog (Александр Неганов)