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 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
     
    to jest rejesrt cien a nie sprzetowy rejestr DMACTL. wartosc z cienia do sprzetowego przenosi VBI.
    • 3:
       
      CommentAuthorxeen
    • CommentTime4 Sep 2013 zmieniony
     
    usunięto - generalnie przyłączałem się do pytania.
    • 4:
       
      CommentAuthorjhusak
    • CommentTime4 Sep 2013
     
    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 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 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 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
     
    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
     
    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 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
     
    Fajny efekt do demka :)
    • 12: CommentAuthorseban
    • CommentTime5 Sep 2013
     
    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
     
    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
     
    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
     
    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
     
    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
     
    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 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
     
    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
     
    OS działa kiedy przerwania są włączone więc możesz być tego pewny :)
    • 23: CommentAuthorxxl
    • CommentTime5 Sep 2013
     
    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
     
    Jeżeli jedno koło jest zepsute, to cały tjaktoj jest to d...
    • 25: CommentAuthor0xF
    • CommentTime5 Sep 2013
     
    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
     
    zgadza sie. dokladnie to opisuje w poscie 18.
    • 27:
       
      CommentAuthormgr_inz_rafal
    • CommentTime5 Sep 2013 zmieniony
     
    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.