Вот в догонку "музыка" для теста экрана УКНЦ ты же воде спрашивал:
https://yadi.sk/d/jX-MxBw87ez5JA
Вот в догонку "музыка" для теста экрана УКНЦ ты же воде спрашивал:
https://yadi.sk/d/jX-MxBw87ez5JA
БK 0010-01, БК 11М, БК11М+,МС 0511 (УКНЦ)х3, Atari 65XE, Commodore 64, AMIGA 500 (HDD), ZX EVO
Manwe, если выбросить синхроимпульс, да и вообще кодировать читаемый бит половиной волны, то есть изменений уровня будет в два раза меньше, не получится ли увеличить скорость до 10Кбит? К примеру каждые 4 бита можно кодировать по такой табличке:
00110011 00100101 00101001 00101011
00101101 00110101 01001001 01001011
01001101 01010011 01011001 01011011
01100101 01101001 01101011 01101101
Единственное неудобство в том, что первое значение имеет только 4 перехода, а не 6. Но если длинную полуволну понимать как 0, то прочитав 4 бита и получив нуль, нужно сразу переходить к трансляции значения и добавлению очередных 4х бит, иначе нужно прочитать еще 2 бита и потом уже делать трансляцию. При таком кодировании соотношение нулей и единиц получается либо равным, либо 3 к 5, что вроде не должно привести к сильному уплыванию уровня. Кроме этого время передачи 4х бит и скорость загрузки всегда будут одинаковыми.
Я сейчас работаю над этим. Первой задачей было выжать максимальную скорость из стандартного загрузчика ПЗУ. А теперь уже можно писать свой загрузчик. Пока что проблема в определении производительности: замеряю подпрограмму, она длится 80 тактов – вроде бы всё логично, по командам так и должно получаться. Заставляю эту же программу читать WAV (с частотой дискретизации вычисленной по формуле N*80) – съезжает синхронизация. Подгоняю частоту WAVа и оказывается что подпрограмма выполняется 82 такта. Как такое может быть – непонятно. Продолжаю исследования.
Update: Удалось добиться скорости 6066 бод - это в два с лишним раза быстрее, чем здесь: https://www.instagram.com/p/BwAfRFXjKJK/
Я пока не сверяю контрольную сумму, но на вид картинка грузится без ошибок. Проблема в том, что частоту дискретизации WAV я подобрал экспериментально (чтобы периоды настроечного тона считывались целое число раз), но эта частота никак не укладывается в целое число тактов процессора (84.6 тактов?!). Формулы нет. Всё наугад. Это чревато тем, что другая БК0010 может и не прочитать WAV с такой частой. Нужны добровольцы с БК0010 для тестов.
Последний раз редактировалось Manwe; 12.04.2019 в 01:34.
manwe.pdp-11.ru
Можно развернуть цикл BIT/BEQ и выбросить счётчик, подстройку нужно будет делать выбирая на какую пару команд перейти, если один из переходов сработает значит импульс короткий, если нет, значит длинный и нужно дождаться его окончание. Общую настройку делаем просто перебирая число команд в развёрнутом цикле и определяя в каком диапазоне читаются только короткие импульсы, а потом будем использовать среднее значение.
У меня другая кодировка: не шириной импульсов, а скважностью. Это удобно тем, что посчитав длину высокого и низкого уровня, я просто сравниваю эти два числа и сразу получаю бит C, который тут же выдвигаю в выходной поток данных.
Развернуть циклы я думал, но это не поможет точно рассчитать частоту – всё равно не сходится с теоретической. В теории с INC цикл длится 56 тактов, а без него 44. Ускорение на 27% (7720 бод) может привести к поднятию частоты на такую, с которой уже не справится источник звука. Но я всё равно попробую что-то такое.
Последний раз редактировалось Manwe; 12.04.2019 в 09:56.
manwe.pdp-11.ru
Спасибо за тему!
У меня есть некоторое количество БК, есть кассеты с играми тех годов. Заказал новый магнитофон teac, т.к моя Вега-122 постоянно барахлит. Я так понимаю для БК0010-01 мне загрузчик и не понадобиться? Буду изучать.
- - - Добавлено - - -
В дополнении хочу сказать. Что в той деке teac которую я заказал есть usb подключение к PC можно сразу оцифровать кассеты которые у меня есть. Может там что есть редкое.
Мои скромные железяки
Altair8800(в процессе)
ATARI 65хе
YAMAHA YIS503IIIR
PackardBell
HP Vectra 286/25n/VE/VL/VL800/VLi8, Kayak XA
AcerPower 433sv
Fujitsu-Siemens Scenic/S 2
Compaq deskpro en
МС 0511-01
Микро80(в процессе)
Микроком85
Апогей-БК01Ц
РадиоРК-86
БК0010/10-01/11/11М
ПК-8000
Львов ПК-01
Агат-9
ДВК-2(в процессе)
ДВК-3М
Вектор-06ц
Специалист
ХТ8088 nec-20
АТ286,386,486
PI-75-200ММХ
РII, III,IV
ZX-Evolution r.C3
Santaka-002
Дельта-С
Ленинград48к
[свернуть]
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Совершенно верно. Просто в конверторе не менять настройки, выбрать файл .bin и нажать кнопку «Сконвертировать». Скачается WAV.
Я воспроизводил WAVы с iPhone и с плеера Sansa Clip, оба на максимальной громкости. БК0010-01 читает без единой ошибки. Если же источник звука некачественный и ошибки случаются, надо снять галочку «Дополнительное ускорение на 11%».
manwe.pdp-11.ru
У меня код чтения получается примерно такой:
В теории, после настройки он может ловить импульсы минимальной длительностью от SET1 до RTS плюс время нескольких пар BIT/BEQ чтобы можно было различать длинные и короткие импульсы. Правда нужно выравнивать длины веток переходы на которые помечены как add NOPS. Настройка заключается в установке LINEH/LINEL на последнюю пару BIT/BEQ(BNE), и попытке приёма одного слова. Затем передвигаем их назад, пока мы не определим весь диапазон устойчивого приёма слов настроечного сигнала, после чего метки нужно поставить посередине. По сравнению с кодированием скважностью, когда 1 бит кодируется двумя полуволнами, здесь для кодирования 4х бит требуется 6 полуволн(и 4 для кодирования комбинации 0000), то есть для скорости 10 кбод, частота будет чуть менее 7500 Гц.Код:MOV AAA,Rbuf ; начало буфера MOV NNN,Rlen ; длина буфера WAITZ: BIT / BNE WAITZ ; вход должен находиться в пассивном состоянии JSR BUFRD ; вызываем функцию чтения BUFRD: MOV 1,Rdata ; регистр для накопления слова c флагом для 16 бит MOVB 4,Ridx ; регистр для накопления индекса с флагом для 6 бит WAITH: BIT / BEQ WAITH ; ждём первый бит BR LINEH ; переходим к измерению длительности ;дальнейший код нужен еще в одном экземпляре для другой полуволны BIT / BEQ SET1 ; если переход сработает значит импульс короткий LINEH: BIT / BEQ SET1 ; положение данной метки настраивается в записимости от скорости BIT / BEQ SET1 WAITL: BIT / BNE WAITL ; переходы не сработали, значит импульс длинный, ждем окончание ;длинный импульс SET0: ASLB Ridx BCS SET2 ; add NOPS флаг индекса вылез, значит получено 6 бит CMPB 64,Ridx BEQ SET2 ; флаг не вылез, но это нуль из 4х бит ASL Rdata ; сдвигаем данные по каждому длинному импульсу BCS SAVE1 ; флаг вылез значит это последняя тетрада слова BR LINEL ; add NOPS ;короткий импульс SET1: ASLB Ridx BCC INC1 ; флаг индекса не вылез, значит нужно только добавить 1 и читать следующую полуволну INC Ridx ; флаг индекса вылез, длинных испульсов было только 2 ASL Rdata ; значит нужно сдвинуть данные еще 2 раза SET2: ASL Rdata BCC SUM1 ; флаг еще не вылез, значит это не последняя тетрада SAVE1: ADD (Table+Ridx),Rdata ; конвертируем индекс по таблице, нуль имеет индекс 64 MOV Rdata,(Rbuf)++ ; сохраняем данные MOVB 4,Ridx ; ставим флаг индекса MOV 1,Rdata ; ставим флаг данных SUB 1,Rlen ; уменьшаем длину BNE LINEL ; читаем другую полуволну RTS INC1: INC Ridx BR LINEL ; add NOPS SUM1: ADD (TableOdd+Ridx),Rdata MOVB 4,Ridx BR LINEL ; add NOPS
Идея с шестью полуволнами хорошая, но я опасаюсь, что что-то может пойти не так во время сохранения прочитанных четырёх бит. Не факт, что удастся подогнать длительность операции сохранения под нужное число тактов (как я писал выше, теоритический расчёт не соответствует практическим данным), и тогда собьётся синхронизация.
У меня уже возникала проблема на границе байта – из-за операций перехода на следующий байт неуверенно читался следующий бит (длинная единица иногда считывалась как короткий ноль). Эту проблему я поборол добавлением 2 к счётчику, но это приблизительное решение (не точно соответствует числу тактов). На другой частоте дискритизации может не сработать.
manwe.pdp-11.ru
Для выравнивания веток лучше всего использовать не NOP, а такие же команды как используются в длинной ветке, а ненужные результаты записывать в Rtemp. Ну а команду сохранения меняем на команду загрузки, только указатель не увеличиваем. Данному коду требуется, чтобы длина короткой полуволны была больше, чем время выполнения от SET1 до RTS, а вместе с пачкой BIT/BEQ была перекрыта и длинная полуволна(иначе будет непонятно где середина устойчивого приёма). Можно для начала сделать и со счётчиком, правда там придётся делать его загрузку, проверку и условный переход, что несколько снизит максимальную скорость приёма. Вообще для выравнивания времени выполнения кода можно сделать следующее:
1) подать на вход сигнал с некоторой частотой(с ним будем сравнивать время выполнения кода)
2) дождаться начала положительного импульса(это нужно будет делать для каждого измерения)
3) выполнить эталонную ветку заменив условные переходы на безусловные
4) скопировать 256 раз состояние входа в память, после чего вывести полученную зебру на экран
5) дождаться нового импульса и выполнить другой код
6) прочитать 256 раз состояние входа и вывести рядом с первым
7) по сдвигу между выведенными полосками мы сможем определить насколько совпадает время их выполнения
8) добавляем или убираем команды и повторяем эксперимент
PS: можно вообще дождаться импульс, после чего 256 раз прогонять код и записывать по 1 значению входа, тогда вид зебр станет одинаковым при идеальной подгонке кода, иначе чем ближе к концу, тем больше будет расползаться.
PPS: Пришла тут мысль, что лучше использовать кодирование 3 длинных/3 коротких, там всего 20 комбинаций, но если выкинуть 011011011, 001001001 и еще парочку, то соотношение 0 и 1 во всех случаях будет 4/5, и код несколько упрощается:
Если нам не требуется фиксированная скорость, и вход позволяет принимать данные при соотношении H и L равном 1 к 2 или наоборот, можно всё существенно упростить, причём ветка с сохранением получается достаточно короткой:Код:LDDAT: MOV 1,Rdata ; флаг для отлова окончания слова LDIDX: MOVB -4,Ridx ; 6 флагов для отлова окончания индекса WAIT0: MOV Tune,Rcnt INC0: DEC Rcnt BIT BNE INC0 ASL Rdata ; всего здесь слово будет сдвинуто 3 раза ASLB Ridx ; индекс двигаем 2 раза чтобы не двигать в длинной ветке ASLB Ridx ASL Rcnt ; добавляем едриницу в предпоследний бит ADCB Ridx ASL Rcnt ADCB Ridx ; add NOPS WAIT1: MOV Tune,Rcnt INC1: DEC Rcnt BIT BEQ INC1 ASL Rcnt ; устанавливаем младший бит индекса ADC Ridx BMI WAIT0 ; add NOPS если индекс еще не закончился ASL Rdata ; 4й раз сдвигаем данные и проверяем не закончилось ли слово BCC BADD ADD (Table+Ridx),Rdata ; сохраняем если закончилось MOV Rdata,(Rbuf)++ DEC Rlen BNE LDDAT RTS BADD: ADD (Table+Ridx),Rdata BR LDIDX ; add NOPS
Код:MOV 1,Rdata MOV Tune,Rcnt WAIT0: DEC Rcnt ; ждём первый и нечётные биты BIT BNE WAIT0 ASL Rdata ASL Rcnt MOV Tune,Rcnt ADC Rdata ASL Rdata ; сдвигаем здесь, чтобы не двигать когда придёт последний бит BCC WAIT2 ; add NOPS WAIT1: DEC Rcnt ; ждём последний бит BIT BEQ WAIT1 ASL Rcnt MOV Tune,Rcnt ADC Rdata MOV Rdata,(Rbuf)++ MOV 1,Rdata DEC Rlen BNE WAIT0 RTS WAIT2: DEC Rcnt ; ждём чётные биты, кроме последнего BIT BEQ WAIT2 ASL Rcnt MOV Tune,Rcnt ADC Rdata BR WAIT0 ; add NOPS
Последний раз редактировалось blackmirror; 13.04.2019 в 22:20.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)