atarionline.pl Wyłączanie ANTIC - opóźnienie - 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:
         
        CommentAuthormgr_inz_rafal
      • CommentTime4 Sep 2013 20:09 zmieniony
       
      Hej,
      Dlaczego taki kod jak poniżej wydaje się wyłączać ANTIC nie od razu, ale tak jakby za chwilę?
      lda #0
      sta SDMCTL ; $22F
      Efekt jest taki, że po wykonaniu tego zapisu do SDMCTL, jeszcze przez ułamek sekundy widać jak zmieniają się kolory i fonty, rozpoczyna się I/O. Dopiero potem ekran gaśnie...
      • 2: CommentAuthorxxl
      • CommentTime4 Sep 2013 20:09
       
      to jest rejesrt cien a nie sprzetowy rejestr DMACTL. wartosc z cienia do sprzetowego przenosi VBI.
      • 3:
         
        CommentAuthorxeen
      • CommentTime4 Sep 2013 20:09 zmieniony
       
      usunięto - generalnie przyłączałem się do pytania.
      • 4:
         
        CommentAuthorjhusak
      • CommentTime4 Sep 2013 20:09
       
      Generalnie: wpis do $D000-$D7FF to wpis do rejestru sprzętowego, nigdzie nie buforowany, przynosi efekt NATYCHMIAST (po cyklu zapisu)

      Na początku pamięci są rejestry tzw-cienie, one służą do pamiętania wartości rejestrów, które są np. tylko do zapisu, a ich odczytywanie przynosi inną wartość (np. rejestry kolorów)
      • 5: CommentAuthorseban
      • CommentTime4 Sep 2013 21:09 zmieniony
       
      Hej!

      Po zapisie do tzw. rejestrów cieni należy poczekać na najbliższe przerwanie VBL aby mieć pewność iż zawartość rejestrów cieni przepisze się do rejestrów sprzętowych.

      Dlaczego piszę o pewności? Bo jeżeli zapiszesz sobie coś do rejestrów cieni a potem wywołasz jakieś I/O, wtedy przez CIO zostanie ustawiona flaga CRITIC ($42), przez co część przerwania VBL odpowiedzialna za przepisanie wartości z rejestrów cieni do rej. sprzętowych zostanie pominięta.

      Gdy chcesz mieć pewność iż zmiany które wprowadziłeś do rej. cieni na pewno się wykonały poczekaj aż nastąpi wykonanie najbliższego VBL, na przykład w taki sposób:

      lda #$00
      sta $22f

      lda #$08
      sta $2c4

      ...
      ...
      ...

      lda $14
      cmp $14
      beq *-2

      ; tutaj już masz pewność iż wszelakie rejestry cienie zostały przepisane do rej. sprzętowych

      i jeszcze kawałek z mapping the atari...

      Mapping The Atari:

      CRITIC

      Critical I/O region flag; defines the current operation as a time-critical section when the value here is non-zero. Checked at the NMI process after the stage one VBLANK has been processed. POKEing any number other than zero here will disable the repeat action of the keys and change the sound of the CTRL-2 buzzer.

      Zero is normal; setting CRITIC to a non-zero value suspends a number of OS processes including system software timer counting (timers two, three, four and five; see locations 536 to 558; $218 to $22E). It is suggested that you do not set CRITIC for any length of time. When one timer is being set, CRITIC stops the other timers to do so, causing a tiny amount of time to be "lost."

      When CRITIC is zero, both stage one and stage two VBLANK procedures will be executed. When non-zero, only the stage one VBLANK will be processed.


      źródło: ->link<-
      • 6:
         
        CommentAuthorxeen
      • CommentTime4 Sep 2013 22:09 zmieniony
       
      chyba nie tłumaczy to efektu, jaki miałem tylko na real Atari. Na emu tego nie miałem. To znaczy efekt krzaczenia był widoczny na pewno "masę czasu" po wpisaniu do rejestru cienia (gdzieś tak sekunda, dwie). Widać już było "podskakujący w zepsuciu" ekran z mojej DL, muzyka grała - ekran po chwili uzyskał synchro - był stabilny. Żadnego I/O podczas krzaków nie miałem. To tak jak na PECE jak się zmienia rozdziałkę to monitor zachowuje się jakby go ktoś kopnął. Potem po uzyskaniu stabliności jak zamieniałem DL w te i w tamte to program zachowywyał się zgodnie z oczekiwaniami. Taki efekt miałem tylko podczas pierwszego uruchomienia. do dzisiaj tego nie rozumiem.

      Oczywiście może to nie mieć związku z wątkiem - bo u mnie efekt był widoczny po włączeniu, a nie po wyłączeniu.
      • 7: CommentAuthorseban
      • CommentTime4 Sep 2013 22:09 zmieniony
       
      Hej!

      Do jakiego rejestru sprzętowego dokonywałeś zapisu? i jakiej wartości? może to było $d400? i chodziło o włączenie lub wyłączenie ekranu?

      edit: czyli dokonywałeś włączenia ekranu przez wpisanie również do rejestru sprzętowego $d400? dobrze rozumiem?
      • 8:
         
        CommentAuthorxeen
      • CommentTime4 Sep 2013 22:09
       
      właśnie nie wiem, czy ten efekt był z tym związany. Ale włączałem poprzez zapisy do 559. potem też dodatkowo do d400 i to pomogło (czysta desperacja - metoda prób i błedów, niestety).
      • 9: CommentAuthorseban
      • CommentTime4 Sep 2013 22:09
       
      Hej!

      Z moich doświadczeń wynika iż to właśnie zapisy bezpośrednio do $d400 bez synchronizacji z VBL powodowały takie efekty. np. dokonywałeś zapisu do $d400, w celu włączenia obrazu np. w połowie ekranu, wtedy Antic często świrował i do GTIA szły jakieś śmiecie, po czym GTIA zaczęło generować jakieś nie poprawne imp. synchronizacji i następowało albo zerwanie synchronizacji pionowej albo wyświetlenie jakichś śmieci. To że Twój TV czy monitor dochodził do siebie po chwili to normalne, mój zielony TWM-315 zbierał się błyskawicznie i poprawny obraz miałem od następnej wyświetlanej ramki. Ale niektóre TV czy mointory znajomych potrafiły kompletnie zgłupieć i zajmowało im kilka ramek zanim ponownie złapały synchronizację.

      Efekt ten zauważyłem po tym jak się stałem posiadaczem turbo2000. Soft na carcie do K.S.O.2000 był tak napisany że przed każdym rozpoczęciem odczytu kolejnego rekordu z kasety wyłączał IRQ, NMI, i wpisywał #0 do $d400, po czym po odczytaniu bloku odblokowywał NMI, IRQ, oraz włączał ponownie ekran. Problem w tym iż następowało to w losowych miejscach ekranu. W zależności od miejsca włączenia lub wyłączenia ekranu miałem efekty z postaci zerwanego synchro, lub innych dziwnych efektów. Trochę mi zajęło zrozumienie dlaczego tak się dzieje... potem poprawiłem trochę kod który znajdował się na carcie...

      Było tak:
      sei
      lda #$00
      sta $d40e
      sta $d400

      ...
      ...
      ...

      cli
      lda #$40
      sta $d40e
      lda $22f
      sta $d400


      moje poprawki polegały na...
      sei
      inc $d40e
      lda $d40b
      bne *-3
      sta $d400

      ...
      ...
      ...

      cli
      lda $d40b
      bne *-3
      lda $22f
      sta $d400
      dec $d40e


      wszelakie efekty uboczne związane ze zrywaniem obrazu ustąpiły :) to chyba tyle moich historycznych wspomnień. Być może napotkałeś ten sam problem ;)
      • 10: CommentAuthorseban
      • CommentTime5 Sep 2013 00:09 zmieniony
       
      sprawdziłem na real hardware, jest tak jak mówiłem gdy będziemy pisać do np. $d400 w losowym miejscu ekranu (a najlepiej w środku linii) osiągniemy różne ciekawe efekty, np. coś takiego:



      testowy kod który umożliwia uzyskanie takiego efektu: (wersja "lite").
      org $480

      st

      ls lda #$40
      cmp $d40b
      bne *-3

      ln lda #$00
      sta $d400

      ldx $d20a

      l1 inc $bc40,x
      dex
      bne l1

      lda #$22
      sta $d400

      ldx $d20a
      l2 dec $bc40,x
      dex
      bne l2

      jmp ls

      run st

      ...a potem aby zobaczyć pełny obraz katastrofy proponuję następnie zamienić "jmp ls", na "jmp ln". Realny efekt jest do osiągnięcia tylko na prawdziwym sprzęcie. Altirra i Atari800 emulują jakieś przesunięcia obrazu jednak nie ma efektów zrywania synchro. Wersja max-sieka wygląda u mnie tak:



      dzięki tym "ubocznym efektom" powstał tryb interlace (480i od Rybags-a) oraz chyba tryb DGF czy jak tam się to zwało.
      • 11: CommentAuthorwieczor
      • CommentTime5 Sep 2013 01:09
       
      Fajny efekt do demka :)
      • 12: CommentAuthorseban
      • CommentTime5 Sep 2013 01:09
       
      ale działa poprawnie tylko na CRT :) rzutniki potrafią pisać "no signal", monitory LCD zazwyczaj pokazują "nic" :P choć zdarzają się takie co potrafią to przetrawić i wyświetlić jakąś namiastkę tego co widać wyżej :)
      • 13: CommentAuthor0xF
      • CommentTime5 Sep 2013 08:09
       
      To zerwanie synchronizacji nie jest bezpośrednio spowodowane zapisami do DMACTL ani nie powoduje wysyłania przez ANTIC śmieci. Po prostu w ostatniej linii obrazu jest hires, co powoduje zrywanie synchronizacji pionowej. Jeśli wyłączymy DMA dla DL w środku ekranu i później włączymy, ANTIC zacznie pobierać DL tam gdzie skończył, w związku z czym następne linie są wyświetlane niżej.

      A różne wyświetlacze reagują na zerwanie synchronizacji różnie. Nawet ten sam CRT raz wyświetli statyczny obraz z "zawiniętą kartką", a czasami będzie skakać.
    1.  
      Oj coś ten nasz Trzmiel tutaj przekombinował ;-)

      Dzięki za liczne odpowiedzi, które - jak to zwykle bywa - rodzą więcej pytań :)

      jhusak:

      Generalnie: wpis do $D000-$D7FF to wpis do rejestru sprzętowego, nigdzie nie buforowany, przynosi efekt NATYCHMIAST (po cyklu zapisu)
      U mnie zmiana "sta SDMCTL" na "sta $d400" powoduje, że Antic wcale się nie wyłącza.

      seban:

      Z moich doświadczeń wynika iż to właśnie zapisy bezpośrednio do $d400 bez synchronizacji z VBL powodowały takie efekty
      Czy więc pisanie do $d400 też jest złym pomysłem?

      Mógłby ktoś wskazać, np. kawałkiem kodu, jak bezpiecznie i bez efektów ubocznych włączać i wyłączać Antic?
      • 15: CommentAuthorxxl
      • CommentTime5 Sep 2013 09:09
       
      musisz sobie odpowiedziec na bardzo wazne pytanie: czy uzywasz OS.

      jesli tak:

      @ lda vcount
      bne @-
      sta dmactls
      sta dmactl

      jesli nie:

      @ lda vcount
      bne @-
      sta dmactl


      > Trzmiel tutaj przekombinował

      nie mial z tym nic wspolnego
      • 16: CommentAuthorwieczor
      • CommentTime5 Sep 2013 09:09
       
      Po pierwsze nie Trzmiel, bo koncepcja 8-bitowego Atari wraz z Antic narodziła się w czasach Atari 400/800 - Trzmiel zrobił ST, a w 8-bitowcach zmienił tylko obudowę ;)
      A poza tym nie przekombinował nikt bo jest to dość logiczne - więcej, to właśnie daj duże możliwości. Chodzi dokładnie o to, że kneblowanie Antica w momencie gdy wyświetla obraz nie jest dobrym pomysłem - trzeba grzecznie poczekać aż skończy ramkę i wtedy. Po to też zostały wprowadzone rejestry cienie - robisz do nich wpis a wartości do prawdziwych rejestrów są przepisywane pomiędzy jednym a drugim obrazem. Możesz skorzystać z cienia, a jeśli nie chcesz żeby przed wyłączeniem obrazu coś się działo, to po prostu poczekaj na ramkę:

      lda #0
      sta sdmctl
      lda 20
      waithere
      cmp 20
      beq waithere


      Kiedy ramka się skończy wartość w 20 zostanie zwiększona i kod pójdzie dalej - ale już po wyłączeniu Antica. Zapis bezpośrednio do rejestru sprzętowego przynosi efekt, ale nie zdążysz go zauważyć, bo przy następnym VBI wartość z cienia zostanie powownie do niego przepisana i Antic zostanie włączony.
    2.  
      Dzięki za rzucenie światła na cienie :) Nareszcie nie mryga...

      Używam OSa i wykorzystałem wersję XXLa - kluczem okazało się zapisanie wartości do cienia i do nie-cienia.
      • 18: CommentAuthorxxl
      • CommentTime5 Sep 2013 10:09
       
      skoro uzywasz niestety ;-) OS to pamietaj o tym, ze pod przerwanie mozna sie podpiac wydluzajac czas wykonywania ponizej linii 0 a wtedy ta procka nie zadziala. mozna oczywiscie zamiast vcount sprawdzac rejestr rtclok ale znowu nalezy pamietac ze procke przerwania mozna zastapic i rejestr rtclok moze nie dzialac. a co jesli procka VBLANK bedzie podmieniona na taka, ktora nie bedzie dbala o dmactls ?

      jednym slowem, jesli uzywasz os niczego nie mozesz byc pewny ;-)
      • 19: CommentAuthorseban
      • CommentTime5 Sep 2013 10:09
       
      Hej!

      Kluczem nie okazało się zapisanie wartości do cienia i nie cienia :) ale kluczem okazało się:

      1) w przypadku procki XXL-a, poczekanie o zerowej linii obrazu i zapis do obu rejestrów (piszę że do obu bo po lda $d40b,bne *-2 jest już dawno po VBL)

      2) równie dobrze działało by to co mówiłem ja i wieczór :) czyli:

      lda #$00
      sta $22f
      lda $14
      cmp $14
      bne *-2


      tutaj wpisujesz do rej. cienia i czekasz aż systemowa procedura VBL przepisze z $22f do $d400 :)

      @fox: masz oczywiście rację :) Ale mi chodził jeszcze o jeden efekt który występuje gdy pisze się po $d400 w środku linii, spróbuje go uchwycić na zdjęciu :) dlatego pisałem o śmieciach które dostaje GTIA (śmieciach w tym sensie że nie jest to żadna sensowana treść obrazu tylko jakieś losowe wartości widoczne na ekranie). Ale masz rację z tym iż zerwanie synchro wiąże się z tym iż program Display List zostaje przesunięty w dół i zaczyna wyłazić za ramkę, a gdy do kompletu mamy tryb hi-res to zerwanie synchro mamy gotowe.
      • 20: CommentAuthormono
      • CommentTime5 Sep 2013 12:09 zmieniony
       
      Ja to dodam tylko może co to jest to magiczne $14 (20), które przedpiśćcy nagminnie podają. W komórce $12 znajduje się 3-bajtowy zegar systemowy RTCLOK, a właściwie licznik zwiększany co każde wywołanie VBLKI (ustawienie CRITIC mu nie przeszkadza, sei też nie). Licznik ten jest little-endian, czyli w $14 znajduje się najmłodszy jego bajt, w $12 najstarszy. Ponieważ zmiany są co VBLK, to sprawdzanie jego zmian to dobra metoda synchronizowania się w programie z końcem przerwania VBLK. Ale:
      1. Kiedy ustawiony jest CRITIC lub sei, wtedy synchronizujesz się z "szybką" częścią VBLK (wektoryzowaną przez VBLKIV=$222) - ta część wykonuje tylko niezbędne rzeczy do działania systemu i nie powinna być nadmiernie obciążana żeby komunikacja przez SIO nie była przez NMI zakłócana.
      2. Kiedy CRITIC nie jest ustawiony i nie ma sei, wtedy prócz VBLKI wykonywana jest również VBLKD (VBLKDV=$224) - część "opóźniona", która może trwać już dość długo. Odpowiada ona za przepisanie rejestrów cieni do rejestrów sprzętowych, testowanie włożenia/wyjęcia carta z gniazda, czy realizację trybu przyciągania uwagi.
      Zazwyczaj obydwie części VBLK są krótkie i kończą się jeszcze zanim zostanie wymalowana pierwsza linia widoczna na ekranie, więc jest to dobra metoda do synchronizowania różnych procesów w programie z powrotem plamki i np. ustawiania rejestrów sprzętowych ANTICa i GTIA.
      Licznik działa oczywiście kiedy OS jest włączony i kiedy przerwania NMI nie są zablokowane.
      Zapis do tego licznika jest rzeczą bardzo brzydką, ponieważ może się okazać, że w systemie został zainstalowany jakiś program (np. zegar czasu rzeczywistego w SpartaDOS), który bazuje na jego zawartości i spowoduje to zakłócenie jego pracy.
      Miłośnikom wyłączania systemu do synchronizacji pozostaje trójca NMIEN/NMIST/NMIRES lub VCOUNT.
      • 21: CommentAuthorxxl
      • CommentTime5 Sep 2013 12:09
       
      bardzo dobry przyklad - a wiec jesli uzywasz os i chcesz synchronizowac sie do rtclok to dodatkowo musisz byc pewny ze przerwania sa wlaczone :D
      • 22: CommentAuthormono
      • CommentTime5 Sep 2013 12:09
       
      OS działa kiedy przerwania są włączone więc możesz być tego pewny :)
      • 23: CommentAuthorxxl
      • CommentTime5 Sep 2013 12:09
       
      oczywiscie nieprawda, po wylaczeniu przerwania NMI VBL tylko czesc os nie dziala, akurat ta odpowiedzialna za m.innymi rtclok a wiec jesli chcesz sie synchronizowac do rtclok musisz byc pewny ze przerwania NMI VBL sa wlaczone :D
      • 24:
         
        CommentAuthorjhusak
      • CommentTime5 Sep 2013 16:09
       
      Jeżeli jedno koło jest zepsute, to cały tjaktoj jest to d...
      • 25: CommentAuthor0xF
      • CommentTime5 Sep 2013 17:09
       
      Co do kodu xxl-a, to czekanie na VCOUNT=0 przy włączonym OS VBLKI chyba nie jest dobrym pomysłem w przypadku NTSC. Albo jeśli mamy na VBLKI player CMC. :)

      Bezpieczniejszy jest kod Sebana - zapis do cienia i zaczekanie, aż VBLKI zadziała. Pewnym mankamentem jest, że nie działa to przy ustawionym CRITIC, ale taki problem występuje tylko przy pisaniu loaderów SIO.
      • 26: CommentAuthorxxl
      • CommentTime5 Sep 2013 17:09
       
      zgadza sie. dokladnie to opisuje w poscie 18.
    3.  
      Dzięki raz jeszcze, widzę, że długa droga przede mną :)

      Zastosowałem rozwiązanie podsunięte przez wieczora/sebana, działa oczywiście tak jak powinno.