Обсуждаем цифровые устройства...
Ответить

Re: Эмулятор магнитофона для ZX-Spectrum

Ср сен 13, 2017 17:16:48

Это не формат tap-файла. :) В tap-файле просто идут один за другим длина блока (2 байта) и его данные. Вот эти данные после пилот-тона и нужно скормить спектруму. А описание у вас как раз формата данных спектрума.
По команде load "" спектрум ждёт заголовка и данных. В заголовке и прописана длина данных (этот самый second block). Но вам-то это зачем нужно? :) Расшифровывать свои магнитофонные файлы будет всё равно сам спектрум.

Re: Эмулятор магнитофона для ZX-Spectrum

Сб сен 16, 2017 10:37:09

Хочу на stm32 собрать для начала плеер tap файлов.

Re: Эмулятор магнитофона для ZX-Spectrum

Сб сен 16, 2017 18:59:48

Так он очень просто делается. Берёте таймер, настраиваете его на некую удобную частоту, пересчитывается посылки сигнала спектрума в число тактов таймера. Ну и выводите прямо как они идут, не забыл про пилот-тон и синхросигнал. Всё. :)

Re: Эмулятор магнитофона для ZX-Spectrum

Вс окт 15, 2017 16:11:04

Всем добра.
Смотрю исходники и не могу найти как же делается пауза между блоками?

Добавлено after 3 minutes 38 seconds:
На сегоднешний момент я уже запуситл на stm32 плеер tap.
Основная логика работы взята из исходника, но у меня идет побайтно считывание с карты, в конце файла идет ошибка т.е. проблема с закрытием и не делает пауз блоков только пилотами

Re: Эмулятор магнитофона для ZX-Spectrum

Вс окт 15, 2017 20:03:44

Если я ещё не полностью забыл, что там сделано, то вот:

Код:
    //формируем паузу
    int delay=200;
    if (BlockSize>0x13) delay=500;//передавался файл
    for(unsigned short n=0;n<delay;n++)
    {
     _delay_ms(10);
     if (BUTTON_SELECT_PIN&(1<<BUTTON_SELECT))//выход
     {   
       TAPE_OUT_PORT&=0xff^(1<<TAPE_OUT);
       return;
     }   
     if (BUTTON_CENTER_PIN&(1<<BUTTON_CENTER))//пауза
     {
     _delay_ms(200);
     while(1)
     {
      if (BUTTON_CENTER_PIN&(1<<BUTTON_CENTER)) break;
     }
     _delay_ms(200);
     }
     if (BUTTON_UP_PIN&(1<<BUTTON_UP))//на блок вперёд
     {
      _delay_ms(200);
      new_block=block+1;
      break;
     }
     if (BUTTON_DOWN_PIN&(1<<BUTTON_DOWN))//на блок назад
     {
      _delay_ms(200);
      if (block>0) new_block=block-1;
      break;
     }
    }
   block=new_block;
    break;   
   }


Когда выдача файла приостановлена ( TapeOutMode==TAPE_OUT_STOP ) программа крутится в этом цикле. Когда блок выдан, режим магнитофона заново выставляется в выдачу пилот-тона ( TapeOutMode=TAPE_OUT_LEAD ). И так до исчерпания файла. Останавливается же выдача файла в прерывании, когда все данные выданы.

Логика работы вот какая:
1) Запускаем цикл для всех блоков файла.
2) Запускаем выдачу блока ( TapeOutMode=TAPE_OUT_LEAD - начинаем с пилот-тона).
3) В прерывании выдаётся блок со всеми синхросигналами и пилот-тоном и данными. Когда всё выдано, выставляем, что блок закончен ( TapeOutMode=TAPE_OUT_STOP ).
3) В основном цикле ждём, когда же прерывание соблаговолит сообщить о том, что блок выдан весь ( TapeOutMode==TAPE_OUT_STOP ). Если это произошло, делаем паузу. Если блок был короткий (длина меньше ли равна 0x13, то считаем его заголовком и паузу делаем меньше, чем если блок точно не заголовок. Это, как правило, работает. Но возможны исключения для коротких файлов данных и нестандартных заголовков).
4) Переходим на шаг 2.

Всё. :)

Re: Эмулятор магнитофона для ZX-Spectrum

Пн окт 16, 2017 15:23:57

У меня синхроимпульсы инверсные

Добавлено after 1 minute 18 seconds:
Код:
/**
* @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts.
*/
void TIM6_DAC_IRQHandler(void)
{
  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */
  /* USER CODE END TIM6_DAC_IRQn 0 */
  HAL_TIM_IRQHandler(&htim6);
  /* USER CODE BEGIN TIM6_DAC_IRQn 1 */      

if (TapeOutMode==TAPE_OUT_STOP)
 {
  index16=16;//первоначальное значение бита
   byte =0;//первоначальное значение байта
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_RESET);//установка в ноль
    //HAL_GPIO_TogglePin(GPIOD, LD6_Pin);
  return;
 }      
  if (TapeOutVolume==true)
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET);
  TapeOutVolume=false;
 }
 else
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_RESET);
  TapeOutVolume=true;
 }
 
  //выводим пилот-тон
 if (TapeOutMode==TAPE_OUT_LEAD)
 {
  TIM6->PSC = 13011;//начальное значение таймера
  if (tim6_countersec > 0) tim6_countersec--;
  else
  {
    tim6_countersec = 3223;
   TapeOutMode=TAPE_OUT_SYNCHRO_1;
   return;
  }
 }
 
 //выводим синхросигнал 1
 if (TapeOutMode==TAPE_OUT_SYNCHRO_1)
 {
  TIM6->PSC =4700;//начальное значение таймера
  TapeOutMode=TAPE_OUT_SYNCHRO_2;
  return;
 }
 
 //выводим синхросигнал 2
 if (TapeOutMode==TAPE_OUT_SYNCHRO_2)
 {
  TIM6->PSC = 4300;//начальное значение таймера
  TapeOutMode=TAPE_OUT_DATA;
  index16=16;
  byte=0;
   BytesCount=0;//обнуляем счетчик байт
  return;
 }

 //передаём данные
 if (TapeOutMode==TAPE_OUT_DATA)
 {   
  if (index16>=16)
  {     
   if (BytesCount>=sz)
   {
    TapeOutMode=TAPE_OUT_STOP;
      //TapeOutMode=TAPE_OUT_PAUSE;//ставим паузу по оканчанию процесса
      //sz=FioNextHead();//читаем размер блока               
      BytesCount = 0;
   return;
   }
   byte=FioNextByte();//читаем байт из буфера
   byte_temp = byte;
   index16=0;//первоначальное значение бита            
   BytesCount++;//общий счетчик байт файла   
  }
  printf("byte_temp %X\r\n", byte_temp);
  //выдаём бит
  if (byte&128) {
      TIM6->PSC = 10265;//начальное значение таймера
      printf("bit%u =1 byte %u\r\n", index16,BytesCount);
   }
            else {
                     TIM6->PSC = 5132;//начальное значение таймера
                     printf("bit%u =0 byte %u\r\n", index16,BytesCount);
                  }
  if ((index16%2)==1) byte<<=1; 
  index16++;
  return;      
 }



Добавлено after 3 minutes 49 seconds:
[img]
Изображение
[/img]

Добавлено after 2 minutes 33 seconds:
Код:
/*---------- файла tap-------------------------------------------------------*/
void read_tap(uint16_t id)
{         
      f_open(&file_tap, fm_curfiles[id]->text, FA_OPEN_EXISTING | FA_READ);
     printf("Open tap\r\n");
   
      sz=FioNextHead();
      TapeOutMode=TAPE_OUT_LEAD;
      //TapeOutVolume=0;
      //printf("Read 0x13 bite tap\r\n");
   while(1)
   {      
   if (TapeOutMode==TAPE_OUT_STOP)
   {
      sz=FioNextHead();
      HAL_Delay(500);
      TapeOutMode=TAPE_OUT_LEAD;
      //TapeOutVolume=0;
   }
      keyboard_update();            
     gui_draw();
      //sys_start_threads();//опрос экрана и клавиатуры    
   }
}



Добавлено after 2 minutes 29 seconds:
Если поменять тут false на true
Код:
 if (TapeOutVolume==true)
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET);
  TapeOutVolume=false;
 }
 else
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_RESET);
  TapeOutVolume=true;
 }

то загрузка пойдет но на последнем блоке окончится ошибкой. Не хватит последнего бита

Добавлено after 2 hours 41 minute 59 seconds:
[youtube]
https://youtu.be/U96scn5DNL0
[/youtube]

вот если поставить
if (TapeOutMode==TAPE_OUT_STOP)
{
index16=16;//первоначальное значение бита
byte =0;//первоначальное значение байта
HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET);//установка в ноль
//HAL_GPIO_TogglePin(GPIOD, LD6_Pin);
return;
}

Re: Эмулятор магнитофона для ZX-Spectrum

Пн окт 16, 2017 20:01:32

У меня синхроимпульсы инверсные


По-моему, это спектруму не важно. С магнитофона же сигнал может быть какой угодно.

то загрузка пойдет но на последнем блоке окончится ошибкой. Не хватит последнего бита


Потому что в прерывании сделано так:
Код:
 if (TapeOutMode==TAPE_OUT_STOP)
 {
  TAPE_OUT_PORT&=0xff^(1<<TAPE_OUT);
  return;
 }

Вам тут тоже нужно будет заменить сигнал на инверсный.

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 05:54:51

Это ваш код
Код:
 if (TapeOutMode==TAPE_OUT_STOP)
 {
  TAPE_OUT_PORT&=0xff^(1<<TAPE_OUT);
  return;
 }
 if (TapeOutVolume==true)
 {
  TAPE_OUT_PORT|=1<<TAPE_OUT;
  TapeOutVolume=false;
 }
 else
 {
  TAPE_OUT_PORT&=0xff^(1<<TAPE_OUT); 
  TapeOutVolume=true;
 }


это у меня (вариант 1)
Код:
if (TapeOutMode==TAPE_OUT_STOP)
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_RESET);//установка выхода в ноль
  return;
 }      
  if (TapeOutVolume==1)
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_RESET);//установка выхода в ноль
  TapeOutVolume=0;
 }
 else
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET);//установка выхода в еденицу
  TapeOutVolume=1;
 }


синхро с еденицы в ноль
[img]
Изображение
[/img]
[img]
Изображение
[/img]

вариант 2
Код:
if (TapeOutMode==TAPE_OUT_STOP)
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET);//установка выхода в еденицу
  return;
 }      
  if (TapeOutVolume==1)
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET);//установка выхода в еденицу
  TapeOutVolume=0;
 }
 else
 {
  HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_RESET);//установка выхода в ноль
  TapeOutVolume=1;
 }


синхро с ноля в еденицу
[img]
Изображение
[/img]
конец файла
[img]
Изображение
[/img]

Загрузка только в таких вариантах, но при загрузке последнего блока из tap файла выдает сообщение об ошибке r-tape error .....

Добавлено after 16 minutes 32 seconds:
ps
У меня STM32 логика 3.3 В
Подключаю напрямую с выхода контроллера ко входу zx spectrum
В спектруме загрузщик не распаян(арлекин 48)
я подключил напрямую ко входу микросхемы.
Может нужна какая ни какая развязка?

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 06:51:11

идя преобразовывать цифру в анал а затем обратно глупая не лучше к старью подключить эмулятор винта нили СD yf базе флехи СF с // фэйсом от старых фотоф
ye или чистый IDE-благо старых приводов до 1гига як гавна на параше и притом задаром

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 06:59:41

Молодой человек, вас это не интересует тогда не спамьте пожалуйста.

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 08:17:02

Может нужна какая ни какая развязка?


Нет, не нужна. Там всё равно компаратор на входе.

А заголовок считывает верно? То есть, "PROGRAMM:" или "bytes:" появляются? Потому что если они появляются, значит, выдача сигнала верная - иначе они бы тоже не считались - они ничем от данных не отличаются. А попробуйте загрузить любую картинку-заставку load "" screen$:pause 0 и посмотрите как она отображается. А то, может, просто у вас с SD карты байты где-то либо теряются, либо перепутаны.

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 09:34:38

[youtube]
https://youtu.be/9JVQ2NzWmuw
[/youtube]

Вот заснял загрузку Диззи.
Грузится и музыку играет в игре виснет.
Другие файлы либо грузит либо после некоторых блоков ошибки.

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 12:56:41

А попробуйте после последнего бита выдать инверсный к нему. То есть, выдавайте последний бит и после окончания выдачи инвертируйте сигнал.

Грузится и музыку играет в игре виснет.


А компьютер-то сам исправен? Стоит прогнать тест ОЗУ.

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 13:04:25

Да компьютер в норме. Тест проходит. Я грузил игры с магнитофона тролля(есть цифровой магнитофон) все в норме. Это что то у меня с проектом.
Еще такой момент, данные я постоянно с карты считываю. То есть не буфиризирую. За каждым байтом на карту

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 14:36:50

Еще такой момент, данные я постоянно с карты считываю. То есть не буферизирую. За каждым байтом на карту


Думаю, STM32 должен успевать. Хотя возможно всякое - где-нибудь пауза проскакивает больше, чем надо, и спектрум воспринимает как другое значение бита.

Но диззи-1 после запуска не должен виснуть - это точно. :) А другие игры тоже виснут после загрузки?

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 15:02:17

не могу выловить в чем проблема. вроде проц мощный F407 168 мегагерц. SD CARD по SDIO

Добавлено after 2 minutes 35 seconds:
Motos тоже загрузилась, в меню выбрал клавиши, запустил и зависла

Добавлено after 1 minute 5 seconds:
Какие сбрасываются, некоторые r tape error

Добавлено after 44 seconds:
Может прерывание где проскакивает.

Добавлено after 34 seconds:
Попробую побольше статистики набрать для анализа.

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 15:21:53

не могу выловить в чем проблема. вроде проц мощный F407 168 мегагерц. SD CARD по SDIO


У этого контроллера 192 кб ОЗУ!!! :) Блок tap больше 64 кб не бывает. Буферизируйте пренепременно!

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 17:53:04

попробую

Добавлено after 29 minutes 56 seconds:
Program Size: Code=23086 RO-data=3282 RW-data=140 ZI-data=93180
93 кб переменные

Добавлено after 2 minutes:
я только в качестве отладки на таком процессоре пока. потом хочу поменьше поставить.

Добавлено after 1 hour 39 minutes 54 seconds:
[img]
Изображение
[/img]

Отловил анализатором глюк.

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 18:06:26

я только в качестве отладки на таком процессоре пока. потом хочу поменьше поставить.


Да, этот процессор очень мощный. :) Я на таком вот что сделал месяц назад: https://youtu.be/-elBzHRjZxo

Отловил анализатором глюк.


Отлично! :)

Re: Эмулятор магнитофона для ZX-Spectrum

Вт окт 17, 2017 18:45:03

Ого. Тепловизор. Что за датчик?
Ответить