ZXNet эхоконференция «zxnet.pc»
тема: вопрос к SMT по исходникам анрила
от: Станислав Ломакин
кому: All
дата: 19 Jan 2006
Hello, All
hi!
пытаюсь портировать куски анрила на линух, начал с ВГ93... скомпилировать
удалось, заставить работать пока нет.
думаю на задержки, все остальное вроде весчь в себе, поэтому вопрос:
в файле wd93cmd.cpp дважды встречается конструкция
┌─- CODE ───
comp.t_states + cpu.t
└── CODE ───
это что такое?
пытался всякую муть сюда пихать (счетчик циклов CPU, счетчик кадров и тп), в
некоторых случаях при попытке чтения диска получалось disc error, в некоторых
-- ошибка чтения... :(
от: SMT
кому: All
дата: 19 Jan 2006
Hello, GriV
глупый вопрос
от: SMT
кому: All
дата: 19 Jan 2006
Hello, boo_boo
> это что такое?
та же самая вроде весчь в себе - это "текущее время" эмулируемого спектрума -
число тактов от старта
вообще, хорошо, что уже есть ощутимые результаты
от: Станислав Ломакин
кому: All
дата: 19 Jan 2006
Hello, SMT
SMT> это "текущее время" эмулируемого спектрума - число тактов от старта
ооо, спасибо! теперь при включенных задержках время опроса дисковода похоже на
реальное...
все равно disc error, впрочем...
хм... после записи в регистр команд команды чтения сектора, и при последующих
попытках что-то взять из регистра данных, младший бит регистра состояния
(занято) перманентно установлен... :confused:
будем думать :)
от: Oleg Golenkoff
кому: All
дата: 19 Jan 2006
Hello, boo_boo
boo> короче, победа, РАБОТАЕТ! надо еще проверить разные загрузчики, и тп,
boo> и тд, но в целом можно сказать, что альфа-версия порта модуля
boo> эмуляции ВГ93 из UnrealSpeccy под линукс готова! :)
классно! :eek: поздравляем ! надеюсь сие чудо можно будет скомпилить под
FreeBSD ? (в будущем :rolleyes: )
от: SMT
кому: All
дата: 19 Jan 2006
Hello, GriV
Gri> но мне очень нужен этот ответ
это зачем "очень"?
сейчас буду говорить много банальностей, умных прошу не читать ^_^
итак, саундблястер играет звук идёт не непрерывным потоком, а небольшими
буферами, состоящими из семплов, для удобства (у меня) по времени равными 1
кадру (1/50 сек.)
имеем на входе переключение бита 4 в порту #FE в некоторые моменты в течение
эмулируемого кадра, а на выходе хотим буфер со звуковыми сэмплами. если частота
оцифровки 48khz, то размер буфера длиной в кадр равен 48000/50=960 семплов.
теперь, задача, как заполнить этот буфер
предположим, что в начале кадра (пентагон, 71680 тактов в кадре) состояние #FE
было 0. а через 5000 тактов туда выведена 1, потом через 5000 тактов - опять 0,
и т.д. (тон в 700 герц). тогда, очевидно, нужно начало буфера заполнить 0 до
семпла номер 66 (5000/71680*960 - пропорция такая), потом от семпла 67 до
семпла 133 (второй вывод на такте 10000, соотв. номер семпла 10000/71680*960)
некоторым ненулевым значением, зависящим от установленной громкости спикера
и так до конца буфера
когда буфер готов, он ставится в очередь звуковой карты на проигрывание (таким
образом, в текущий момент практически во всех эмуляторах играют буферы от
прошлого и даже, более вероятно, позапрошлого или поза- поза- прошлых кадров,
но приходится с этим мириться в обмен на другие прелести эмуляторов)
в реальности мы видим, что из-за погрешностей округления при расчётах позиции
семпла смены уровня, расстояния между фронтами в буфере не одинаковые, поэтому
(и ещё по паре причин) возникают паразитные частоты (т.н. альясинг). что это
такое и как с ними бороться, написано в любом более-менее уважающем себя
учебнике по ЦОС, лучше мне и не сказать. рекомендую http://dsp-book.narod.ru
ну если уж такая лень открыть учебник, может, когда-нить и накатаю популярную
лекцию типа этой
от: SMT
кому: All
дата: 19 Jan 2006
Hello, SMT
вернее, дело не в CRC (она, похоже, верная), а в том, что спектрум не нашёл код
#10 в нужном месте системного сектора диска. либо TRD такой (c чистым 9-м
сектором disc error - правильное поведение), либо данные не доходят до
процессора из образа диска. всё равно проверь загрузчик TRD
от: SMT
кому: All
дата: 19 Jan 2006
Hello, SMT
похоже, спектрум нашёл и прочитал данные. вероятно, ошибка в загрузчике
TRD-файлов, который сформировал неверные CRC для секторов (можно загрузить и
сразу выгрузить в формате UDI, а потом сравнить с windows-версией). однако CRC
для адресных меток сформированы верно (63,9B для 6-го сектора)
от: SMT
кому: All
дата: 19 Jan 2006
Hello, boo_boo
GriV, слишком общий вопрос. всё равно, что рассказать "из каких соображений"
телевизор показывает картинку. развёрнутый ответ сейчас не могу дать
boo, если догадаюсь в чём дело, напишу
от: SMT
кому: All
дата: 19 Jan 2006
Hello, boo_boo
ты взял глюкалку или фуз?
от: Valery Grigoriev
кому: All
дата: 19 Jan 2006
Hello, SMT
SMT> GriV, слишком общий вопрос. всё равно, что рассказать "из каких
SMT> соображений" телевизор показывает картинку. развёрнутый ответ сейчас
SMT> не могу дать
Хорошо я подожду, но мне очень нужен этот ответ.
от: Valery Grigoriev
кому: All
дата: 19 Jan 2006
Hello, SMT
SMT> глупый вопрос
Вообще ничего не вижу глупого, может всё таки ответишь?
от: Знахарь
кому: All
дата: 19 Jan 2006
Hello, GriV
SMT - профессионал! Сразу видно, ибо "только проф. программеру проще объяснить,
почему нельзя написать что-то, чем написать" :) кажется так было написано :)
Boo boo - молодец! Давай эмуль под линуха... Думаю там очередь желающих. Я,
кстати, тоже не против.
от: Станислав Ломакин
кому: All
дата: 19 Jan 2006
Hello, GriV
оооо, точно, блин, вот же я идиот -- сплошные нули читаются ^____^
нелюбовь к глобальным переменным меня подвела -- распихивая их по классам, не
обратил внимания на конструкцию
memset(this, 0, sizeof(FDD)); :p
короче, победа, РАБОТАЕТ! надо еще проверить разные загрузчики, и тп, и тд, но
в целом можно сказать, что альфа-версия порта модуля эмуляции ВГ93 из
UnrealSpeccy под линукс готова! :)
от: Станислав Ломакин
кому: All
дата: 19 Jan 2006
Hello, SMT
SMT> ты взял глюкалку или фуз?
глюкалку... весь день долблюсь, без толку. впрочем, я довольно приблизительное
представление имею о работе ВГ, так что оно не удивительно...
вот лог обращения к ВГ -- может, по нему видно, на каком этапе пошли глюки?
┌─- CODE ───
file /home/boo/!ZX/CM2DEMO.trd loaded in drive A
Захожу в TRDOS:
WD OUT(0xff,0x00) status = 10000000
WD OUT(0xff,0xff) status = 100
WD OUT(0x1f,0xd0) status = 10000100
32 раза: {
WD OUT(0xff,0xf7) status = 10000100
WD OUT(0xff,0xff) status = 10000100
}
Делаю CAT:
WD OUT(0xff,0x3c) status = 10000100
WD OUT(0x1f,0x08) status = 101 /*восстановление*/
WD IN(0xff)=0xbf status = 100 /*INTRQ*/
WD IN(0x1f)=0x24 status = 100100 /*состояние*/
2408 раз {
WD IN(0x1f)=0x26 status = 100110 /*дергаем состояние*/
}
WD OUT(0x1f,0x08) status = 100111 /*восстановление*/
WD IN(0xff)=0xbf status = 100100 /*INTRQ*/
WD OUT(0x7f,0x20) status = 100100
WD OUT(0x1f,0x18) status = 100111 /*поиск дорожки*/
WD IN(0xff)=0xbf status = 100100 /*INTRQ*/
WD OUT(0x7f,0x01) status = 100000
WD OUT(0x1f,0x18) status = 100011 /*поиск дорожки*/
WD IN(0xff)=0xbf status = 100000 /*INTRQ*/
WD IN(0x1f)=0x22 status = 100010
WD OUT(0x7f,0x00) status = 100000
WD OUT(0x1f,0x18) status = 100011 /*поиск дорожки*/
WD IN(0xff)=0xbf status = 100000 /*INTRQ*/
WD IN(0x1f)=0x26 status = 100110
WD OUT(0xff,0x3c) status = 100110
WD IN(0x1f)=0x26 status = 100110
WD IN(0x3f)=0x00 status = 100110
WD OUT(0x7f,0x00) status = 100100
WD OUT(0x1f,0x18) status = 100111 /*поиск дорожки*/
WD IN(0xff)=0xbf status = 100100 /*INTRQ*/
WD OUT(0x1f,0xc0) status = 100111 /*чтение адреса*/
WD IN(0xff)=0x3f status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x06 status = 1
WD IN(0xff)=0x3f status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x01 status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x63 status = 1
WD IN(0xff)=0x3f status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x9b status = 1
WD IN(0xff)=0xbf status = 0 /*INTRQ*/
WD OUT(0x3f,0x00) status = 0 /*уст. 0 дорожку*/
WD OUT(0xff,0x3c) status = 0
WD IN(0x1f)=0x00 status = 0
WD IN(0x3f)=0x00 status = 0
WD OUT(0x7f,0x00) status = 0
WD OUT(0x1f,0x18) status = 1 /*поиск дорожки*/
WD IN(0xff)=0xbf status = 100100 /*INTRQ*/
WD OUT(0x1f,0xc0) status = 100101 /*чтение адреса*/
WD IN(0xff)=0x3f status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x09 status = 1 /*данные*/
WD IN(0xff)=0x3f status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x01 status = 1 /*данные*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x73 status = 1 /*данные*/
WD IN(0xff)=0x3f status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0xa5 status = 1 /*данные*/
WD IN(0xff)=0xbf status = 0 /*INTRQ -- прочитали адрес*/
WD OUT(0x3f,0x00) status = 0 /*уст. 0 дорожку*/
WD OUT(0xff,0x3c) status = 0
WD IN(0x3f)=0x00 status = 0
WD OUT(0x7f,0x00) status = 0
WD IN(0x3f)=0x00 status = 0
WD OUT(0x1f,0x18) status = 1 /*поиск дорожки*/
WD IN(0xff)=0xbf status = 100100 /*INTRQ*/
WD OUT(0x3f,0x00) status = 100100 /*уст. 0 дорожку*/
WD OUT(0x5f,0x09) status = 100100 /*уст. 9 сектор*/
WD OUT(0x1f,0x80) status = 100101 /*чтение сектора*/
WD IN(0xff)=0x3f status = 1
30 раз: {
WD IN(0xff)=0x7f status = 11 /*DRQ*/
}
около 100 примерно таких кусков: {
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x3f status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x7f status = 11 /*DRQ*/
WD IN(0x7f)=0x00 status = 1 /*данные*/
WD IN(0xff)=0x3f status = 1
WD IN(0xff)=0x7f status = 11 /*DRQ*/
}
WD IN(0xff)=0xbf status = 0 /*INTRQ -- считали 9й сектор*/
WD IN(0x1f)=0x00 status = 0 /*состояние -- типа все ок*/
WD OUT(0xff,0x37) status = 0 /
15 раз: {
WD OUT(0xff,0x3f) status = 10000000
WD OUT(0xff,0x37) status = 10000000
}
WD OUT(0xff,0x3f) status = 10000000
WD OUT(0xff,0x34) status = 10000000
15 раз: {
WD OUT(0xff,0x3c) status = 0
WD OUT(0xff,0x34) status = 0
}
WD OUT(0xff,0x3c) status = 0
Получаю Disc Error
└── CODE ───
UPD: хммм, выглядит так, будто вместо 9го сектора считалось хрен знает что, по
случаю чего ошибка. но фигли тогда сошлась контрольная сумма? :confused:
от: SMT
кому: All
дата: 20 Jan 2006
Hello, boo_boo
кста, выше я обшибся, не 700hz, а 350 в примере
от: Станислав Ломакин
кому: All
дата: 20 Jan 2006
Hello, breeze
bre> классно! :eek: поздравляем ! надеюсь сие чудо можно будет скомпилить
bre> под FreeBSD ? (в будущем :rolleyes: )
пасиб ;)
сам выдранный из US ВГ93-эмулятор под чем угодно соберется -- там только
стандартные сишные библиотеки юзаются. ZX-эмуль, на котором экспериментирую
сейчас -- искореженная глюкалка, если обычная глюкалка пашет под фрей, то и с
этим хозяйством не должно быть проблем :cool:
от: Valery Grigoriev
кому: All
дата: 20 Jan 2006
Hello, SMT
ладно я понял, меня как раз антиалиасинг интересует.
Тут ведь дело в чём - например тот же dizzy выводит на стартовой заставке
(оригинальная версия имеется в ввиду) вполне приличный музон - если просто
тыркать состояние бипки в звуковой ряд, то ничего путёвого не выйдет - прото
потому что в указанный отрезок времени - даже для 48кгц получается около 73
тактов - он (бипка) изменяет своё состояние и даже порой не один раз и конечно
оттуда и вопрос. Hа реальном спекке как - имеется триггер на выходе бипки и SPK
и имеется его внутренняя ёмкость которая приводит к немоментальному
срабатыванию триггера - например в течении нескольких мкс изменяет свой уровень
на противоположный (сигнал не прямоугольной формы). Т.е. в любом случае имеется
немоментальный переход в противоположное состояние, а потом я изучил диаграммы,
получаемые US - и получается так же - что сигнал у бипки изменяется не
моментально прямоугольно - а через некоторое количество отсчётов - порядка 1-2
отсчётов выходного звукового ряда (48 кгц всё те же). Вот и оттуда вопрос -
откуда этот "наклон" кривой изменения состояния бипки? Это его именно
антиалиасинг даёт?
от: SMT
кому: All
дата: 20 Jan 2006
Hello, GriV
да
|