atarionline.pl Filterek do Blizzarda - Forum Atarum

    Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

    • :
    • :

    Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

      • 1: CommentAuthoradi
      • CommentTime31 Aug 2024 04:08
       
      Oto prosty filterek do Turbo Blizzard.

      Po puszczeniu Blizzarda przez smartfon, sygnał jest zniekształcony. Podobne zniekształcenia widziałem w postach Sebana dla wyjścia z magnetofonu.
      Filterek załatwia sprawę definitywnie.
      Oto schemat:
      • 2: CommentAuthoradi
      • CommentTime31 Aug 2024 04:08
       
      Oto oscylogram po wyjściu sygnału ze smartfonu:
      • 3: CommentAuthoradi
      • CommentTime31 Aug 2024 04:08 zmieniony
       
      A ten na wyjściu filtra.
      Zwróćcie proszę uwagę, że pomiar długości impulsu w Blizzardzie zaczyna się i kończy na opadających zboczach impulsów, a tam właśnie robiło się "przegięcie".
      • 4: CommentAuthoradi
      • CommentTime5 Sep 2024 20:09 zmieniony
       
      Filterek wraz z komparatorem.
      Testowany na zrzucie kasety Blizzard, zamieszczonym przez Sebana.
      • 5: CommentAuthoradi
      • CommentTime12 Sep 2024 22:09
       
      Komparator z poprzedniego posta działał tylko w symulacji. W rzeczywistym układzie zawiodło symetryzowanie wejścia na dzielnikach rezystorowych.

      Zadziałał inny układ:
      • 6: CommentAuthoradi
      • CommentTime12 Sep 2024 23:09
       
      I jeszcze obraz z oscyloskopu przy pomiarze rzeczywistego układu.
      Kolor fioletowy - sygnał na wejściu (ze smartfona, głośność na max).
      Kolor niebieski - sygnał za cewką filtru.
      Kolor seledynowy - sygnał na wyjściu wzmacniacza operacyjnego (skala 1:10).
      • 7: CommentAuthoradi
      • CommentTime17 Sep 2024 23:09 zmieniony
       
      Pokonałem temat ładowania Blizzarda przez Arduino. Tzn. Arduino pełni rolę Atari.
      W schemacie z poprzedniego postu zamieniłem wzmacniacz operacyjny LM358 na komparator LM393.
      Bardzo poprawił się kształt impulsów wyjściowych.

      Arduino na razie odczytuje po 20 znaków z każdego bloku Blizzarda.
      Wynik z monitora portu szeregowego na zrzucie ekranu poniżej.
      Krzaki to binarna treść kolejnych bloków River Raida.

      Podłączenie do Arduina przez wejście cyfrowe D7.
      Kod programu na Arduino:
      const byte BlizzardPin = 7;

      // typy impulsów w Blizzard
      #define impSynchro 2
      #define impOne 1
      #define impZero 0

      // typy bloków w Blizzard
      #define blkSynchro 0
      #define blkName 1
      #define blkData 2

      volatile uint8_t last_pulse_type;
      volatile uint8_t actual_block_type;
      volatile uint8_t last_block_type;
      volatile uint16_t number_of_synchro_pulses = 0;
      volatile uint8_t actual_start_bit = 0;
      volatile uint16_t byte_number = 0;
      volatile uint8_t byte_mask = 1;

      volatile unsigned long actual_micros;
      volatile unsigned long last_micros;
      volatile uint16_t pulse_width;

      volatile byte Blizzard_file_name[20];

      void setup() {
      // debug:
      Serial.begin(115200);
      Serial.println("Start programu.");

      pinMode(BlizzardPin, INPUT_PULLUP);
      PCICR |= B00000100;
      PCMSK2 |= B10000000;
      }

      void loop() {
      }

      ISR (PCINT2_vect)
      {
      if (digitalRead(BlizzardPin) == LOW) {
      actual_micros = micros();
      pulse_width = actual_micros - last_micros;

      if (pulse_width > 599)
      // czas impulsu dłuższy niż 600us (w Blizzardzie będą to zakłócenia)
      {
      }

      else if (pulse_width > 374)
      // czas impulsu między 375us a 600us (w Blizzardzie będzie to impuls synchro)
      {
      if (number_of_synchro_pulses == 0) {
      for(int i = 0; i < 20; ++i) {
      Serial.print((char)Blizzard_file_name[i]);
      }
      Serial.println();
      }
      byte_mask = 128;
      byte_number = 0;
      Blizzard_file_name[0] = 0;
      last_pulse_type = impSynchro;
      number_of_synchro_pulses = number_of_synchro_pulses + 1;
      }

      else if (pulse_width > 207)
      // czas impulsu między 375us a 208us (w Blizzardzie będzie to impuls "1")
      {
      if (byte_number < 20) {
      Blizzard_file_name[byte_number] |= byte_mask;
      byte_mask >>= 1;
      if (byte_mask == 0) {
      byte_number++;
      Blizzard_file_name[byte_number] = 0;
      byte_mask = 128;
      }
      }
      last_pulse_type = impOne;
      }

      else if (pulse_width > 121)
      // czas impulsu między 208us a 122us (w Blizzardzie będzie to impuls "0")
      {
      if (last_pulse_type == impSynchro)
      {
      if (number_of_synchro_pulses > 2048)
      {
      // czyli jesteśmy w bloku Synchro
      actual_block_type = blkSynchro;
      } else {
      // czyli jesteśmy w bloku innym niż Synchro
      if (actual_block_type == blkSynchro)
      {
      actual_block_type = blkName;
      } else {
      actual_block_type = blkData;
      }
      }
      number_of_synchro_pulses = 0;
      actual_start_bit = 1;
      } else {
      // czyli poprzedni impuls nie był impulsem synchro
      if (actual_start_bit == 1)
      {
      actual_start_bit = 2;
      } else {
      // czyli skończyły się dwa bity startowe
      actual_start_bit = 255;

      if (byte_number < 20) {
      byte_mask >>= 1;
      if (byte_mask == 0) {
      byte_number++;
      Blizzard_file_name[byte_number] = 0;
      byte_mask = 128;
      }
      }
      }
      }
      last_pulse_type = impZero;
      }

      else
      // czas impulsu krótszy niż 122us
      {
      }

      last_micros = actual_micros;
      }

      }
      • 8: CommentAuthoradi
      • CommentTime19 Sep 2024 14:09 zmieniony
       
      Puściłem na wcześniej przygotowany układ (filtr+komparator+Arduino_Uno) dźwięk z nagraniem Atari tape normal.
      Bez problemu można rozpracować ciągi impulsów reprezentujące zera i jedynki.
      Na razie mam tylko programik wyświetlający diodą wbudowaną w Arduino rekordy danych Atari:

      const byte ledPin = 13;
      const byte InputPin = 7;

      volatile unsigned long actual_micros;
      volatile unsigned long last_micros;

      void setup() {
      pinMode(ledPin, OUTPUT);
      pinMode(InputPin, INPUT_PULLUP);
      pinMode(testPin, OUTPUT);
      PCICR |= B00000100;
      PCMSK2 |= B10000000;
      }

      void loop() {
      }

      ISR (PCINT2_vect)
      {
      uint16_t pulse_length;

      if (digitalRead(InputPin) == LOW) {
      actual_micros = micros();
      pulse_length = actual_micros - last_micros;

      if (pulse_length > 300)
      // czas impulsu dłuższy niż 300us (w Normalu będą to zakłócenia)
      {
      digitalWrite(LED_BUILTIN, LOW);
      }

      else if (pulse_length > 209)
      // czas impulsu między 210us a 300us (w Normalu będą to impulsy składające się na "0")
      {
      digitalWrite(LED_BUILTIN, HIGH);
      }

      else if (pulse_length > 150)
      // czas impulsu między 150us a 210us (w Normalu będą to impulsy składające się na "1"
      // albo impulsy pilota)
      {
      digitalWrite(LED_BUILTIN, LOW);
      }

      else
      // czas impulsu krótszy niż 150us
      {
      digitalWrite(LED_BUILTIN, LOW);
      }

      last_micros = actual_micros;
      }

      }


      Wygląda na to, że Arduinem da się "obskoczyć" każde nagranie kasetowe dla Atari (normal i różne turba). Czyli można stworzyć uniwersalny interfejs smartfon -> Atari.
      Wyzwaniem będzie pewnie mityczne Turbo2600 ze Świebodzina, ale pewnie też do pokonania.
      • 9:
         
        CommentAuthorMq
      • CommentTime19 Sep 2024 15:09
       
      Tak się tylko wtrącę w Twój monolog: są ludzie, którzy to czytają i śledzą Twoje prace z tym projektem, więc niech Cię nie zraża to, że nikt nie odpisuje i kontynuuj prace. Projekt jest wg mnie ciekawy i chętnie czytam o szczegółach, oraz ciekaw jestem dokąd dobrniesz i jaki będzie efekt końcowy. A że nic nie piszę... hmm... no ja akurat nie mam tu za bardzo nic do powiedzenia, bo nie bawiłem się nigdy elektroniką magnetofonową Atari za bardzo...
      • 10: CommentAuthoradi
      • CommentTime19 Sep 2024 16:09 zmieniony
       
      Mq - Dzięki wielkie za wsparcie :)

      A tak wracając do technikaliów:
      Wav-y puszczane ze smartfona generowałem doskonałym programem Baktry - Turgen.
      Baktra był tak dokładny, że elegancko wyliczał sinusoidę i dbał, aby przy zmianie częstotliwości 5.327/3.995 nie było uskoków.
      Bit w Atari normal trwa tyle samo dla "0" jak i "1", a że są to inne częstotliwości, to w bicie "0" mieści się inna ilość okresów sinusoidy niż w "1".
      Pokey przy nagrywaniu w normalu nie jest tak subtelny i wali wprost przebiegiem prostokątnym. Przebieg ten wygładzają kondensatory w magnetofonie i sama taśma.
      === Edit =====
      Tu po głębszym zastanowieniu straciłem pewność.
      Może Pokey wykorzystuje swoje umiejętności muzyczne i wysyła na DataOut sygnał analogowy? Trzeba doczytać...
      ==============
      W efekcie na głowicy przy wczytywaniu też mamy coś podobnego do sinusoidy, ale przejścia pomiędzy zerami i jedynkami nie są tak gładkie jak u Baktry.
      Czyli Arduino dekodując bity będzie musiało uśredniać przynajmniej po kilka.
      Dla Turbo2600 jeden bit to tylko dwa okresy sinusoidy. Może być ciężko.
      • 11:
         
        CommentAuthorjhusak
      • CommentTime19 Sep 2024 19:09
       
      Jest tak, jak pisze Mq!
      • 12:
         
        CommentAuthorKaz
      • CommentTime19 Sep 2024 19:09
       
      Potwierdzam. Czytam, śledzę, nie komentuję, uczę się :)
      • 13: CommentAuthorZenon
      • CommentTime19 Sep 2024 20:09
       
      Na wszystkim nie musimy się znać, ale uczyć i śledzić TAK
      • 14: CommentAuthorbaktra
      • CommentTime19 Sep 2024 23:09
       
      POKEY, w trybie dwutonowym, wyprowadza fale kwadratowe o dwóch różnych częstotliwościach do DATA OUT. Wygładzanie sygnału jest konsekwencją ograniczonego zakresu częstotliwości taśmy magnetycznej i obwodu nagrywającego.
      • 15: CommentAuthoradi
      • CommentTime19 Sep 2024 23:09 zmieniony
       
      Kaz, Zenon - zawstydzacie mnie :).

      A tak wracając do tematu transmisji normal: przetestowałem interfejs na zrzucie z autentycznej taśmy (pobranym z adresu ->link<- ).
      Muszę odszczekać, co wcześniej napisałem o braku gładkości w przejściach pomiędzy 0 i 1.
      Okazuje się, że przejścia te prezentują się bardzo dobrze.
      Na zrzucie poniżej przebieg seledynowy to nagranie darts.mp3
      a fioletowy to wyjście z komparatora.
      • 16: CommentAuthoradi
      • CommentTime19 Sep 2024 23:09
       
      Przebieg z taśmy faluje, zmienia amplitudę ale to nie powinno przeszkadzać interfejsowi.
      Poniżej zrzut w większej skali.
      Jak widać przebieg na wyjściu komparatora jest stabilny i trzyma długości impulsów.
      • 17:
         
        CommentAuthorMq
      • CommentTime20 Sep 2024 00:09
       
      Mnie się wydaje, że na real-sprzęcie te przejścia między zerami i jedynkami będą zawsze gładkie, bo w gruncie rzeczy mówimy tu o sygnale analogowym, a ten wpada w pewną bezwładność związaną z pojemnościami, które to "ułagodniają". Ale to tylko takie moje filozoficzne spostrzeżenie:-)
      • 18: CommentAuthoradi
      • CommentTime20 Sep 2024 09:09 zmieniony
       
      A może częstotliwości reprezentujące zera i jedynki zostały specjalnie tak dobrane, żeby przebieg wychodził gładki?

      Tzn. dla 9-ciu okresów sinusoidy 5,327kHz będziemy mieli 1,689ms, a dla 7-miu okresów
      sinusoidy 3,995kHz będzie 1,752ms.
      Różnica tylko o 3,5%.

      Czyli zwiększając prędkość transmisji trzeba trzymać się pełnych ilości impulsów
      0,187ms i 0,250ms.
      W przeciwnym przypadku poszarpie nam fazę.
      Dodatkowo długość bitu zerowego musi być taka sama jak jedynki.
      To właściwie tłumaczy dlaczego turba oparte o FSK były takie słabe.

      Edit:
      Chociaż...
      Pewnie i tak w Pokey-u nie ma dokładnej regulacji częstotliwości, tylko jest ustawianie dzielnika w timerze.
      Zawsze wychodzą pełne ilości impulsów. Zmienia się tylko ich częstotliwość.
      Czyli zostaje problem wyrównania długości zer i jedynek w FSK, a dla transmisji przyśpieszonych problem nie trafienia w częstotliwości filtrów w magnetofonie.
      • 19:
         
        CommentAuthorMq
      • CommentTime20 Sep 2024 09:09
       
      Może Pokey generuje po prostu określoną ilość impulsów z określoną częstotliwością i tak to generuje, a nie robi tego przez określony czas generując daną częstotliwość. Pokey robi prostokąt, więc zawsze jest równe przejście między stanami, no to później następstwem tego sinus też jest zawsze równy.
      • 20: CommentAuthoradi
      • CommentTime20 Sep 2024 13:09 zmieniony
       
      Mq: Pewnie masz rację. Nawet zacząłem przeszukiwać system operacyjny Atari (https://data.atariwiki.org/DOC/Atari_400-800_Technical_Reference_Notes-Operating_System_User_s_Manual-Operating_System_Source_Listing_and_Hardware_Manual_553_pages.pdf), żeby to potwierdzić, ale w końcu zaniechałem, bo moim celem jest stworzenie czegoś nowego a nie rozpoznanie jak to kiedyś działało.
      • 21: CommentAuthoradi
      • CommentTime20 Sep 2024 15:09 zmieniony
       
      Oto, w sumie banalny, programik dekodera FSK na Arduino.
      Jak Adruino napotyka dwa kolejne impulsy Mark włącza na DataIn stan wysoki. Jak napotyka dwa następujące po sobie impulsy Space włącza stan niski.

      Nie mam jak sprawdzić na realnym sprzęcie.
      Za dwie godziny będę miał dostęp do oscyloskopu i analizatora stanów logicznych to prześlę zrzuty.

      const byte ledPin = 13;
      const byte InputPin = 7;
      const byte OutputPin = 4;

      // typy impulsów w Normal
      #define impSpace 0
      #define impMark 1
      #define impNone 2

      volatile unsigned long actual_micros;
      volatile unsigned long last_micros;
      volatile uint8_t last_pulse_type = impNone;

      void setup() {
      pinMode(ledPin, OUTPUT);
      pinMode(OutputPin, OUTPUT);
      pinMode(InputPin, INPUT_PULLUP);
      PCICR |= B00000100;
      PCMSK2 |= B10000000;
      }

      void loop() {
      }

      ISR (PCINT2_vect)
      {
      uint16_t pulse_length;

      if (digitalRead(InputPin) == LOW) {
      actual_micros = micros();
      pulse_length = actual_micros - last_micros;

      if (pulse_length > 300)
      // czas impulsu dłuższy niż 300us (w Normalu będą to zakłócenia)
      {
      digitalWrite(LED_BUILTIN, LOW);
      last_pulse_type = impNone;
      }

      else if (pulse_length > 209)
      // czas impulsu między 210us a 300us (w Normalu będą to impulsy składające się na "0")
      {
      digitalWrite(LED_BUILTIN, HIGH);
      if (last_pulse_type == impSpace) {
      digitalWrite(OutputPin, LOW);
      }
      last_pulse_type = impSpace;
      }

      else if (pulse_length > 150)
      // czas impulsu między 150us a 210us (w Normalu będą to impulsy składające się na "1"
      // albo impulsy pilota)
      {
      digitalWrite(LED_BUILTIN, LOW);
      if (last_pulse_type == impMark) {
      digitalWrite(OutputPin, HIGH);
      }
      last_pulse_type = impMark;
      }

      else
      // czas impulsu krótszy niż 150us
      {
      digitalWrite(LED_BUILTIN, LOW);
      last_pulse_type = impNone;
      }

      last_micros = actual_micros;
      }

      }
      • 22: CommentAuthoradi
      • CommentTime20 Sep 2024 19:09
       
      Okazuj się, że ten prosty programik działa zaskakująco dobrze.
      Na rzucie kolejno:
      - przebieg na wyjściu smartfona (zrzut kasety darts.mp3 opisany wcześniej)
      - przebieg na wyjściu komparatora
      - przebieg na wyjściu z Arduina
      • 23: CommentAuthoradi
      • CommentTime20 Sep 2024 19:09
       
      I jeszcze zrzut w większej skali. Jest to koniec pilota i pierwsze dwa bajty synchronizujące $55, $55. Widać niewielkie różnice w szerokości impulsów, ale Atari powinno dać radę wczytać.
      Szkoda, że nie mogę sprawdzić na realnym sprzęcie.
      • 24: CommentAuthorzaxon
      • CommentTime20 Sep 2024 20:09
       
      Ja też kibicuję i trzymam kciuki.
      • 25: CommentAuthoradi
      • CommentTime20 Sep 2024 21:09
       
      Nie byłbym sobą, gdybym nie spróbował FSK na Turbo2600 :).
      Tu niestety uśrednianie dwóch pierwszych impulsów nie zadziałało, bo tu są tylko po 2 impulsy na bit.
      Pojechałem więc "po bandzie" i ustawiłem zmianę DataOut już po pierwszym impulsie.
      Programik na Arduino nawet się uprościł:

      const byte ledPin = 13;
      const byte InputPin = 7;
      const byte OutputPin = 4;

      volatile unsigned long actual_micros;
      volatile unsigned long last_micros;

      void setup() {
      pinMode(ledPin, OUTPUT);
      pinMode(OutputPin, OUTPUT);
      pinMode(InputPin, INPUT_PULLUP);
      PCICR |= B00000100;
      PCMSK2 |= B10000000;
      }

      void loop() {
      }

      ISR (PCINT2_vect)
      {
      uint16_t pulse_length;

      if (digitalRead(InputPin) == LOW) {
      actual_micros = micros();
      pulse_length = actual_micros - last_micros;

      if (pulse_length > 300)
      // czas impulsu dłuższy niż 300us (w Normalu będą to zakłócenia)
      {
      digitalWrite(LED_BUILTIN, LOW);
      }

      else if (pulse_length > 209)
      // czas impulsu między 210us a 300us (w Normalu będą to impulsy składające się na "0")
      {
      digitalWrite(LED_BUILTIN, HIGH);
      digitalWrite(OutputPin, LOW);
      }

      else if (pulse_length > 150)
      // czas impulsu między 150us a 210us (w Normalu będą to impulsy składające się na "1"
      // albo impulsy pilota)
      {
      digitalWrite(LED_BUILTIN, LOW);
      digitalWrite(OutputPin, HIGH);
      }

      else
      // czas impulsu krótszy niż 150us
      {
      digitalWrite(LED_BUILTIN, LOW);
      }

      last_micros = actual_micros;
      }
      }


      Do testu wziąłem nagranie przygotowane przez Sebana w tym wątku na atari.org.pl: ->link<-

      Plik "draconus (T2600, DB, 2600 bps).wav"
      Blok 9 (nagrany z prędkością 2663bodów):
      • 26: CommentAuthoradi
      • CommentTime20 Sep 2024 21:09
       
      Na oscyloskopie wyglądało to tak jak poniżej.
      Nie mam pewności czy jest OK, bo nie wiem jaki jest układ bitów startowo-stopowych.
      Wygląda ładnie.
      Bajty powinny być takie, jak na rzucie z poprzedniego postu (czyli 00,00,FF,FF,FF,FF,FE,FC,FC,F8,..).
      • 27:
         
        CommentAuthorjhusak
      • CommentTime20 Sep 2024 22:09 zmieniony
       
      Podejrzewam (takie moje przemyślenia), że ten rodzaj modulacji zadziała w przypadku dobrych nagrań. A takie, co są przykasowane troszkę i kołyszą głośnością, mogą mieć problemy. Jak robiłem dekoder do mojego archiwizatora dyskietek ->link<- to jako przejście stanu brałem maksymalną pochodną pomiędzy próbkami. Można jeszcze dalej pójść i zrobić interpolację na dwóch największych pochodnych, wtedy można by wczytywać sygnały samplowane np. 8 khz, bo punkt przegięcia (druga pochodna równa 0) byłby gdzieś między próbkami, a ten czas zwiększa rozdzielczość próbkowania wielokrotnie (kilkudziesięciokrotnie). Wiem, bo robiłem kiedyś interpolację położenia punktu tablicy interaktywnej, i z 256 punktów rozdzielczości (wymiar x lub y) robiłem stabilne 4096 punktów (16000 punktów już szumiało). Wycinałem też bad piksele, bo się zdarzały. To przez naszą firmę Hamamatsu zmodyfikowało datasheet swojego układu, bo mieli zbyt dużo reklamacji od nas. A jak zmienili, to właśnie zacząłem wycinać te bad piksele i interpolować na podstawie sąsiednich. I problem bad pixeli zniknął. Tylko trzeba było je wykryć, a robiło się to podgrzewając układ i skanując matrycę w ciemności.

      Także ten, interpolacja w razie czego działa cuda. Na 3 punktach, wychodzi ładna parabolka :)
      • 28: CommentAuthoradi
      • CommentTime21 Sep 2024 05:09 zmieniony
       
      Kuba, oczywiście masz rację, tylko że moim celem nie jest archiwizowanie jakiś starych kaset.
      Zaczęło się od tego, że potrzebuję jakiejś pamięci masowej dla komputerków tworzonych na mikrokontrolerach i tego w całości na TTL-ach.
      Z sentymentu, wolę żeby była to pamięć oparta o dźwięk.
      Wybrałem Turbo Blizzard i zacząłem do niego tworzyć interface. W komputerku TTL zarządzającym klawiaturą i startem jest Arduino.
      Czyli potrzebuję, żeby Arduino odczytywało ze smartfona kolejne bajty i ładowało je do pamięci komputerka.

      Jak widać we wcześniejszych postach, Arduino może stanowić również bardzo skuteczny interfejs do Atari. Tu ma łatwą rolę, bo tylko ustawia wejście DataIn.
      Poza tym, są turba, dla których nie ma w Polsce dostępnych interfejsów (Turbo2600, Sistema Injector, Turbo EMO).
      A są to systemy bardzo ciekawe, głównie dlatego, że nie wyłączają ekranu podczas ładowania.
      Chętnie pobawiłbym się nimi na realnym sprzęcie.
      Może to niedługo nastąpi... :).

      p.s. Puściłem na interface i obejrzałem na oscyloskopie program Bonk.wav w Sistema Injektor (dostępny tutaj: ->link<- ).
      Nie będę Was już męczył zrzutem ekranu.
      Progam składa się z części w normalu i tej w turbo.
      W turbo występują tylko impulsy 250us i 500us (4 i 2kHz).
      Czyli Arduino będzie musiało zdekodować część normal (FSK) a potem przełączyć się na dekodowanie długości impulsu (PWM).
      Dość proste zadanie.
      Filtr i komparator nie wymagają żadnych zmian.
      • 29: CommentAuthoradi
      • CommentTime21 Sep 2024 17:09
       
      Na stronie ->link<- opisany jest (po hiszpańsku) spósob działania Injektora.
      Zmiana stanu na wyjsciu DataIn następuje przy każdym wystąpieniu długiego impulsu.
      Pytanie tylko jaki stan ma mieć DataIn na początku?
      • 30: CommentAuthoradi
      • CommentTime22 Sep 2024 07:09 zmieniony
       
      Żeby przetestować Injektora bez realnego Atari, potrzebuję jakiegoś programu w wersjach .wav i .cas .
      Chilijczycy jakoś konwertują nagrania z Injektora do CAS-ów i twierdzą, że można je ładować przez SDrive Max lub na emulator Altira.
      Np. ->link<-
      po przetłumaczeniu googlem:

      "Po kilku miesiącach urodziłam pierwszego wtryskiwacza za 256 tys., ten w wersji demonstracyjnej. Ta gra, którą wam zostawiam, jest przeznaczona tylko na Atari z rozszerzeniem 256k, COMMANDO 256k, którą jako pierwszą wydano na kasecie był Vitoco o czasie trwania około 33 minut, teraz zajmuje to tylko 9:56 sekundy, wielka magia Injektora, tylko do załadowania do emulatora sdrive lub altirra."

      CAS (zrzut ekranu poniżej) wygląda jakby w całości opisywał nagranie w FSK. Jednak w punkcie 6 widać, że przełącza prędkość na 3995 bodów.
      Przypuszczam, że chodzi o przebieg na DataIn, który jest już zdemodulowany Injektorem i od strony Atari wygląda na nomalny przebieg szeregowy.
      • 31: CommentAuthoradi
      • CommentTime22 Sep 2024 15:09 zmieniony
       
      Coś tam wychodzi (zrzut na końcu), podobnego do oryginału:



      Programik na Arduino jest banalny:

      const byte InputPin = 7;
      const byte OutputPin = 4;

      volatile unsigned long actual_micros;
      volatile unsigned long last_micros;
      volatile bool actual_DataIn = true;

      void setup() {
      pinMode(OutputPin, OUTPUT);
      pinMode(InputPin, INPUT_PULLUP);
      PCICR |= B00000100;
      PCMSK2 |= B10000000;
      }

      void loop() {
      }

      ISR (PCINT2_vect)
      {
      uint16_t pulse_length;

      // w Injektorze przełączenie wyścia następuje przy długim impulsie górnym bądź dolnym
      // czyli łapiemy oba zbocza w przerwaniu PIN-Change

      actual_micros = micros();
      pulse_length = actual_micros - last_micros;

      if (pulse_length > 186)
      // czas impulsu między 187us a 325us (w Injektorze będą to impulsy długie)
      {
      // długi impuls w Injektorze oznacza zmianę stanu wyjścia na przeciwny
      actual_DataIn = ! actual_DataIn;
      digitalWrite(OutputPin, actual_DataIn);
      }


      last_micros = actual_micros;
      }
      • 32: CommentAuthoradi
      • CommentTime22 Sep 2024 21:09 zmieniony
       
      Na Github-ie dostępny jest pełen kod Injektora:
      ->link<-
      Niestety nie mam tyle doświadczenia w programowaniu Atari, aby go szybko przeanalizować.
      • 33:
         
        CommentAuthorjhusak
      • CommentTime23 Sep 2024 11:09
       
      Dzięki za ten linek!
      • 34: CommentAuthoradi
      • CommentTime23 Sep 2024 12:09
       
      A8dogdark ma na Github-ie komplet CAS-ów z grami w Injekorze:
      ->link<-

      I emulator z wkompilowaną biblioteką a8cas:
      ->link<-

      Można ładować CAS-y Injektora (i innych turbo) bezpośrednio do emulatora.
      • 35: CommentAuthoradi
      • CommentTime23 Sep 2024 16:09
       
      Do kopiowania dysk->Injektor służy program Ultra 256K Converter.
      Trzeba wystartować Atari z dyskietki:
      ->link<-

      Opis programu jest tu:
      ->link<-
      • 36:
         
        CommentAuthorjhusak
      • CommentTime23 Sep 2024 16:09
       
      Czy jest gdzieś nowsze repozytorium a8cas niż to a8cas.sourceforge.net?
      • 37: CommentAuthoradi
      • CommentTime24 Sep 2024 01:09
       
      Kopiarka, o której pisałem w poprzednim poście nagrywa programy max. 1400 bodów.
      Wersja Injektor 4000 bodów wraz z opisem (po hiszpańsku) jest tutaj: ->link<-
      • 38: CommentAuthoradi
      • CommentTime24 Sep 2024 01:09 zmieniony
       
      Trochę jest namieszane z tymi Injektorami. Jest kilka wersji:
      "NHP to record 600 BAUD
      8NHP to record NHP 800 BAUD
      STAC to record 900 BAUD
      ULTRA to record in 1150 BAUD
      SUPUL to record SUPER ULTRA 1400 baud."

      I najważniejsza: Coelsa Injektor 4000 bodów.
      Tej ostatniej żaden emulator nie wczytuje.
      Potrzebny jest realny Atari i realny interface.
      Jedyne nagranie jakie mam to gra Bonk w wav-ie: ->link<-
      CAS-a do Coelsa Injektor nikt jeszcze nie stworzył (albo o tym nie wiem), choć nie wykluczam, że jest to możliwe.

      Nie ma też dostępnego kodu źródłowego.
      Github Dogdark-a, o którym wcześniej pisałem, zawiera kody źródłowe do wersji o mniejszych prędkościach.
      • 39: CommentAuthoradi
      • CommentTime24 Sep 2024 12:09 zmieniony
       
      Zasymulowałem proces zapisu w Coelsa Injektor.
      Aby uzyskać przebieg podobny do bitów danych, podłączyłem dwa generatory przez bramkę XOR.
      Wynikowy, żółty oscylograf to przebieg prądu w głowicy magnetofonu.
      Do prądu będzie proporcjonalny poziom sygnału na taśmie.
      Wynik symulacji jest bardzo podobny do rzutu z oryginału, który zamieściłem kilka postów wyżej.

      Wniosek: Jeśli jest długi impuls dolny trzeba na DataIn ustawiać poziom niski. Jeśli jest długi impuls górny - ustawiać poziom wysoki.
      Jeśli są krótkie impulsy w górę lub w dół - nie robić nic.
      • 40: CommentAuthorascrnet
      • CommentTime24 Sep 2024 17:09 zmieniony
       
      Oryginalna wersja Coelsa Injektor posiada system ochrony wykorzystujący prawdziwy sprzęt. Teraz ATR udostępniony przez Dogdark jest wersją zmodyfikowaną bez tego zabezpieczenia i działa bez problemów z dużą prędkością, ale z szybkością 3900 bodów.

      Załączam przykład wersji niechronionej.(cas)


      kolejny przykład wersji chronionej.(mp3)
      ->link<-
      • 41: CommentAuthoradi
      • CommentTime25 Sep 2024 03:09 zmieniony
       
      Dzięki wielkie Ascrnet :)

      Nawet nie wiesz jak mi pomogłeś.
      Dostarczyłeś brakującego elementu do układanki.
      Zrozumiałem jak zapisywane są bity w Coelsa Injektor.
      Na zrzucie ekranu jest moje ręczne rozkodowanie czwartego bloku "21-joust - coelsa injektor.mp3".
      Bajty startowe dokładnie zgadzają się bajtami z czwartego bloku "Coelsa Injektor Hack.cas".

      Teraz droga do wykonania interfejsu na Arduino stoi otworem.
      • 42: CommentAuthoradi
      • CommentTime25 Sep 2024 10:09 zmieniony
       
      Coelsa Injektor pokonany przez Arduino!

      Poniżej zrzut analizatora stanów logicznych podłączonego do wyjścia Arduina.
      Na wejście interfejsu podłączony smartfon z plikiem "21-joust - coelsa injektor.mp3".
      Zrzut to początek 4-go bloku (czyli pierwszego w turbo).
      Bajty zgodnie w 100%.
      • 43: CommentAuthoradi
      • CommentTime25 Sep 2024 10:09
       
      I jeszcze kod programu Arduina, oraz zrzut początku właściwego Joust-a (poprzedni zawierał blok drivera).

      const byte InputPin = 7;
      const byte OutputPin = 4;

      volatile unsigned long actual_micros;
      volatile unsigned long last_micros;
      volatile bool input_state;

      void setup() {
      pinMode(OutputPin, OUTPUT);
      pinMode(InputPin, INPUT_PULLUP);
      PCICR |= B00000100;
      PCMSK2 |= B10000000;
      }

      void loop() {
      }

      ISR (PCINT2_vect)
      { // we catch both edges in the PIN-Change interrupt
      uint16_t pulse_length;
      input_state = digitalRead(InputPin);
      actual_micros = micros();
      pulse_length = actual_micros - last_micros;

      if (pulse_length > 325)
      { // pulse time above (in the Injektor these will be random signals)
      digitalWrite(OutputPin, HIGH);
      }

      else if (pulse_length > 186)
      { // pulse time above 187us a 325us (in the Injektor these will be long pulses)
      if (input_state == LOW) {
      // long impulse ended with a falling edge
      digitalWrite(OutputPin, LOW);
      } else {
      // long pulse ended in a raising edge
      digitalWrite(OutputPin, HIGH);
      }
      }
      last_micros = actual_micros;
      }
      • 44: CommentAuthorascrnet
      • CommentTime25 Sep 2024 19:09
       
      Proszę bardzo, jestem zainteresowany tematem. Ale czy ładuje je już na Atari, czy tylko widzisz falę transmisji?

      Załączam jeszcze 3 gry w formacie mp3 :)
      ->link<-
      • 45: CommentAuthoradi
      • CommentTime25 Sep 2024 19:09 zmieniony
       
      Nie mam w domu realnego Atari.
      Sprawdzałem tylko falę transmisji na analizatorze stanów logicznych.
      Program analizatora potrafi sprawdzać poprawność protokołu UART (który jest zgodny z SIO Atari).
      Większość bloków Joust.mp3 przeszło bez błędów ramki.
      Sum kontrolnych analizator nie liczy.
      Na niektórych blokach były błędy ramki ale to pewnie dlatego, że jeszcze nie stroiłem dekodera na Arduino.
      Strojenie będzie polegało na dobraniu zakresów czasów impulsów.
      Na razie bardzo cieszę się, że cokolwiek dało się w locie rozkodować.
      Zaraz podłączę układ i sprawdzę pozostałe pliki mp3.

      Tak ogólnie jestem pod wielkim wrażeniem Inektora.
      U nas w Polsce nie udało się wypracować takiego doskonałego rozwiązania.
      Systemy turbo nie korzystały z przerwania Pokey-a.
      A u Was można jednocześnie ładować grę z prędkością 4000 bodów, mieć włączony ekran a na dodatek grać na nim w grę (podczas ładowania), która sama odtwarza dźwięki.
      Jestem pod wielkim wrażeniem!

      === Edit ===

      Dla niewtajemniczonych: obejrzeć w działaniu Injektora można na emulatorze (do pobrania stąd: ->link<- ). Pod Linuxem można go odpalać za pomocą Wine.
      W emulatorze trzeba uruchomić plik "Coelsa Injektor Hack.cas" zamieszczony kilka postów wyżej przez Ascrnet.
      Instrukcja użycia jest tutaj:
      ->link<-
      • 46: CommentAuthorascrnet
      • CommentTime25 Sep 2024 21:09
       
      zrozumiałe, wówczas dowód koncepcji zakończył się pełnym sukcesem :)

      Ciekawie będzie zobaczyć, jak podłączyć go do portu SIO i załadować na ATARI.
      • 47: CommentAuthoradi
      • CommentTime25 Sep 2024 22:09 zmieniony
       
      Porównałem blok nr 4 rozkodowany w locie z "06-brucelee - coelsa injektor.mp3" z blokiem 4 z "Coelsa Injektor Hack.cas".
      Wszystkie bajty są identyczne oprócz 5 ostatnich, które są zupełnie inne.
      Może to część zmienna (np. nazwa pliku), albo modyfikacja kodu naniesiona przez Dogdark.
      • 48: CommentAuthoradi
      • CommentTime25 Sep 2024 22:09 zmieniony
       
      A to jakieś teksty z bloku numer 6 - również rozkodowanego w locie przez Arduino.

      === Edit ===
      Trochę przetłumaczyłem Googlem:
      "Przewiń taśmę do początku taśmy- Naciśnij PLAY i RETURN Jeśli błąd występuje wielokrotnie: -Sprawdź ładunek za pomocą kasety, która jest w dobrym stanie Zwilż czystą gazę alkoholem -Ostrożnie wyczyść głowicę i rolkę dociskową -Sprawdź azymut swojego graweru"
      • 49: CommentAuthoradi
      • CommentTime26 Sep 2024 10:09 zmieniony
       
      Trochę analizowałem kod Injektora udostępniony przez Dogdark:
      ->link<-

      Loader czeka 2 sekundy na przełączenie interface na turbo:
      CLC         ; ESPACIO
      LDA 20 ; ENTRE 600
      ADC #120 ; Y 4K
      WAITFOR4000
      CMP 20
      BNE WAITFOR4000


      Potem, w procedurze obliczania prędkości transmisji czeka na pierwszy bit statowy:
      BRATE = $02EE
      CALCULORAM
      SEI
      LDA #$00
      STA $D40E
      STA $D400
      STA BRATE
      STA BRATE+1
      LDA $D20F
      AND #$10
      STA $0316
      STARTBIT
      LDA $D20F
      AND #$10
      CMP $0316
      BEQ STARTBIT


      Później mierzy odległość (czasową) między bitem startowym a bitem B5=HIGH w pierwszym bajcie (#$20). Odległość ta powinna wynosić 6*250us = 1.5ms

      STA $0316
      LDY #$0A
      BAUDRATE
      INC BRATE
      LDA $D20F
      AND #$10
      CMP $0316
      BEQ BAUDRATE
      STA $0316
      DEY
      BNE BAUDRATE
      LDY #$09
      BITSDEMAS
      LDA $D20F
      AND #$10
      CMP $0316
      BEQ BITSDEMAS
      STA $0316
      DEY
      BNE BITSDEMAS
      CLC
      LDA BRATE
      ADC #$04
      STA BRATE


      Czyli procedura jest zupełnie inna niż ta w normalu oparta o bajty $55, $55.
      Stąd brak w blokach turbo tych bajtów.
      • 50: CommentAuthoradi
      • CommentTime26 Sep 2024 13:09 zmieniony
       
      Wpadłem na pomysł jak mogę sprawdzić poprawność działania interface Injektor bez dostępu do realnego Atari.
      Można pozyskane z Arduina dane wpisać do CAS-a i spróbować załadować CAS-a przez emulator.
      Aby wypełnić CAS-a potrzebuję dokładnej prędkości transmisji turbo.
      Realna prędkość zależy od ustawień silników: magnetofonu nagrywającego oryginał i tego, na którym był zgrany do WAV-a.
      Nagrałem analizatorem z dużą częstotliwością próbkowania początek bloku turbo w Joust.mp3.
      Okazało się, że czas 1.5ms jest bardzo dokładnie zachowany:

      === Edit ===
      Sprostowanie: w CAS-ie trzeba wpisać prędkość 4000, bo tu szybkość silnika nie ma nic do rzeczy.
      Prędkość skorygowaną trzeba użyć przy dekodowaniu UART(SIO) w programie analizatora stanów logicznych.
      W drugim pliku (10-dkjr - coelsa injektor.mp3) pomiar czasu dał wynik 1.51ms. Czyli w analizatorze musiałem wpisać częstotliwość 4027Hz. Po tej korekcie nie było żadnych błędów ramki.