Yello!
Mam pewną procedurkę w VBL'u, która rysuje co ramkę coś na ekranie, tyle że podczas wyświetlania pojawiają się pewne drobne niepożądane efekty.

Korzystam z trybu GTIA - 80x59, 16 odcieni i po cztery linie o tym samym adresie. W pewnych miejscach (okolice środka ekranu) szwankuje synchronizacja i domyślam się że przyczyną jest moje (niewłaściwe?) podejście do VBL'a. Ustawienie adresu procedury wygląda tak:

    lda 20
    cmp 20
    beq *-2

      sei
    lda #0
    sta $d40e     ;wyłączamy nmi
    lda #$fe
    sta $d301     ;wyłączamy OS

    lda #<nmi
    sta $fffa
    lda #>nmi
    sta $fffb       ;adres przerwania

    lda #$40
    sta $d40e    ;zezwalamy tylko na vbl

I po tym następuje już tylko:

loop    jmp loop

I odtąd praktycznie działa już tylko przerwanie. Wygląda tak:

_day    ldy #0
    jsr efekt
    inc _day+1

    rti

Efekt jest więc liczony podczas powrotu pionowego, podczas którego jeśli dobrze rozumiem, Antic czeka aż VBL zakończy działanie. VBL się kończy, Antic przystępuje do wyświetlania linii, a w tym czasie program nie modyfikuje zawartości ekranu, dlaczego więc w pewnych miejscach niektórych linii pojawia się coś np. takiego:

01 43 [>]12 21 23[<] 13 ... etc, aż do czterdziestego bajtu  \
01 43 [>]34 44 51[<] 13 ... etc                               >4 linie o tym samym adresie
01 43 [>]86 00 64[<] 13 ... etc                              / 
01 43 [>]11 21 23[<] 13 ... etc                             /

hm?

I jeszcze jedno: kiedy obciążę tą procedurkę graficzną trochę bardziej, to przez kilka(-naście,-dziesiąt,-set, zależnie od obciążenia) pierwszych ramek norma jest wyrabiana, a potem procedura przerwania zdaje się nie móc dobrnąć do końca.

Co należy zrobić żeby wyeliminować usterki?

2

śmigło .::. napisał/a:

Efekt jest więc liczony podczas powrotu pionowego, podczas którego jeśli dobrze rozumiem, Antic czeka aż VBL zakończy działanie. VBL się kończy, Antic przystępuje do wyświetlania linii,

Co rozumiesz przez "VBL" tutaj? Procedurę obsługi przerwania? Bo jeśli tak, to Antic oczywiście nie czeka na jej zakończenie - ale może co innego masz na myśli, a co innego ja rozumiem.

KMK
? HEX$(6670358)

3 Ostatnio edytowany przez xxl (2006-11-03 22:24:56)

śmigło .::. napisał/a:

I jeszcze jedno: kiedy obciążę tą procedurkę graficzną trochę bardziej, to przez kilka(-naście,-dziesiąt,-set, zależnie od obciążenia) pierwszych ramek norma jest wyrabiana, a potem procedura przerwania zdaje się nie móc dobrnąć do końca.

Co należy zrobić żeby wyeliminować usterki?

napisac procke, ktora sie wyrobi w ramce

to nie zlosliwosc, ale nie napisales nic o procedurze do ktorej skaczesz, moze jest "za dluga" ?

i jeszcze jedno, jesli jest tak jak piszesz to znaczy ze ingerujesz w rejestr dmacontrol (a chyba tego nie robisz) podczas przerwania?

http://atari.pl/hsc/ad.php?i=1.

4

średnio VBL daje do dyspozycji 20.000 cykli CPU, w tylu cyklach trzeba się zmieścić ze swoimi procedurkami

aby pozbyć się zrywania synchronizacji, trzeba użyć dwóch buforów, jeden pokazujesz, na drugim operujesz itd.

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

5 Ostatnio edytowany przez śmigło .::. (2006-11-04 16:19:34)

drac: troszkę namieszałem... vbl jako procedura o nazwie #nmi. To jest ten fragment:

nmi
_day ldy #0
          jsr efekt
          inc _day+1

         rti

xxl: obniżyłem do ok. 16 000 cykli (w najgorszym wypadku) i problem z liniami dalej obecny :(. Dmactl natomiast podczas przerwania nie jest modyfikowany. Znaczy że powinien być?

6

a gdzie masz na przerwaniu odkładanie i zdejmowanie wartosci rejestrow, chyba nie jesteś aż tak zaawansowany aby z tego rezygnować

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

7

A po co mu to, skoro główny program się składa tylko z jmp * ?

KMK
? HEX$(6670358)

8

> obniżyłem do ok. 16 000 cykli (w najgorszym wypadku) i problem z liniami dalej obecny

zjedz jeszcze bardziej 20 tys to z tego co pamietam ilosc cykli miedzy wywolaniami przerwania wygaszania pionowego

> Dmactl natomiast podczas przerwania nie jest modyfikowany. Znaczy że powinien być?

niekoniecznie, zadalem to pytanie bo... atari to maszyna dwuprocesorowa ;-) i antic nie czeka na 6502 czy skonczy czy nie obsluge przerwania.

sprobuj moze tak (bo niewiem co oznacza klopoty z synchronizacja o ktorych wspominasz) po skonczonym przerwaniu zapodaj jakas losowa wartosc do colbak zobaczysz w ktorym miejscu "konczy " sie Twoj prg przerwania

http://atari.pl/hsc/ad.php?i=1.

9

"zjedz jeszcze bardziej 20 tys to z tego co pamietam ilosc cykli miedzy wywolaniami przerwania wygaszania pionowego"

Zauważyłem dziwną (?) rzecz. Jak wspominałem, ekran ma rozmiar 80x59. Efekt wykorzystuje z tego obszar maksymalnie 80x44 (i pożera 21 600 cykli). Wtedy 15 linii na dole jest nietkniętych. Jeżeli przesuniemy obraz o te 15 linii w dół, tak że to część górnej połowy jest nietknięta, migotanie w okolicach środka już nie występuje i synchro się trzyma.

Jeżeli ktoś wie dlaczego dopiero w takich warunkach, prosiłbym o wyjaśnienie.

W każdym razie dzięki wszystkim za pomoc! :)

10

bylo to opisane chyba w de re atari, to co robisz na vbi moze byc widoczne w tej (nie Twoj przypadek bo procka za dluga) lub w nastepnej ramce (Twoj przypadek - dokonujesz operacji na obrazie PO jego narysowaniu w danej ramce)

http://atari.pl/hsc/ad.php?i=1.

11

śmigło .::. napisał/a:

Zauważyłem dziwną (?) rzecz. Jak wspominałem, ekran ma rozmiar 80x59. Efekt wykorzystuje z tego obszar maksymalnie 80x44 (i pożera 21 600 cykli). Wtedy 15 linii na dole jest nietkniętych. Jeżeli przesuniemy obraz o te 15 linii w dół, tak że to część górnej połowy jest nietknięta, migotanie w okolicach środka już nie występuje i synchro się trzyma.
Jeżeli ktoś wie dlaczego dopiero w takich warunkach, prosiłbym o wyjaśnienie.

Pomyśl jak kreślony jest obraz i w którym momencie w pamięci ekranu (relative to plamka :) rysujesz swoje dzieło.
Po prostu nieświadomie utrafilłeś na moment kiedy podmiana ramki na nowo narysowaną odbywa się w momencie kiedy dany fragment ekranu nie został jeszcze narysowany. Plamka dolatuje do miejsca w którym ma sie pojawić obraz no i tam już jest nowa ramka :) i nic nie miga :)

Generalnie masz dwa wyjscia:
1. prostsze, juz zaproponowane przez Tebe - dwubuforowanie.
2. trudniejsze, i po czesci nieswiadomie przez ciebie wykonane, a opisane przez Foxa w Atarynce rysowanie linii względem plamki :) (że się tak wyrażę)

ps. gdybym cos pomylil to koledzy poprawią :)