76

(6 odpowiedzi, napisanych Programowanie - 16/32bit)

Hmmm. Mam pomysł, jak uszczknąć około 10-15% czasu ramki :D (o ile oczywiście da się to zrealizować), ale wymaga to sporej zmiany w kodzie. Może kiedyś przysiądę i zrobimy najszybsze wypełnianie 4 bitplanowego trójkąta na STeku :P

77

(6 odpowiedzi, napisanych Programowanie - 16/32bit)

Można zamienić tablicę masek/offsetów na tablicę masek/offsetów lewą i tablicę masek/offsetów prawą. Wtedy zamiast dwóch lsl.w #3,d0 i lsl.w #3,d1 będą podwójne dodawania add.w d0,d0; add.w d0,d0 i add.w d1,d1; add.w d1,d1. To da oszczędności 12 cykli na linię wypełniającą. Jak będę miał chwilę czasu, zrobię odpowiednie zmiany.

78

(6 odpowiedzi, napisanych Programowanie - 16/32bit)

Możemy spróbować kod jeszcze trochę zoptymalizować, a później można spróbować wrzucić go gdzieś dalej. ENDC - dodałem. Co ciekawe, kompilowało mi się bez zakończenia kompilacji warunkowej... Dziwne.

79

(6 odpowiedzi, napisanych Programowanie - 16/32bit)

Żeby zakończyć cykl wypełnianych trójkątów :P ,na koniec 2-4 bitplanowy triangle filler. Ilość bitplanów reguluję się stałą "planes" na początku programu. Sprawdziły się przypuszczenia, że 4 bitplany na blitterze będą szybsze od tych na motoroli (ale różnica nie powala). Samo wypełnianie pojedynczych planów jest NAPRAWDĘ szybkie, szkoda że sporo czasu traci się na przygotowanie blittera do pracy. :( Żeby sprawdzić czas w ramce, naciskamy tradycyjnie Ctrl.

80

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

saulot napisał/a:

niedokładnie przeczytałeś, napisałem 'ustawić bit#3 na 0' , tym razem nie zrobiłem sobie wioski ;) ..

Hehehehe.. Ale ty podstępny jesteś! :P Rzeczywiście... Ustawić na zero... :D

81

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

saulot napisał/a:

To ustawienie bitu #5 w $fffffa11 przed rte nie jest konieczne jak sobie ustawimy bit#3 na 0 pod $FFFA17 . (wersja dla leniwych ;))

Wszystko OK, tylko że leniuchy powinny sobie ten bit wyczyścić, a nie ustawić... :P

82

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

Na koniec małe podsumowanie całości i zebranie wszystkich naszych sugestii. Żeby odpalić swój timer C (200Hz), bez oglądania się na system i jego wartości należy:

1. Wyłączyć przerwania
2. Zainstalować sobie pod $114 własną procedurę.
3. Wyczyścić bity 4-6 rejestru kontrolnego timera C i D (adres $fffffa1d, ja czyszczę całość, bo timera D też nie chce mieć odpalonego) - mamy wtedy pewność, że timer będzie wyłączony do momentu jego ponownego uruchomienia.
4. Włączyć przerwania

Jeśli teraz będziemy chcieli załączyć timer C, wpisujemy #$40 pod $fffffa1d, #246 pod $fffffa23, ustawiamy bity 5 w adresach $fffffa09 i $fffffa15.

Procedura przerwania musi kończyć się wyczyszczeniem 5 bitu $fffffa11 no i oczywiście rte

83

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

saulot napisał/a:

ugh, to była niefortunna przeklejka ;) ..

powinno być:
        move.l    update,$114.w        ;slap interrupt
        move.b    #246,$fffffa23.w    ; set data
        andi.b     #$0f,$fffffa1d.w     
        ori.b        #$a0,$fffffa1d.w       ; div mode 50
        bset.b    #5,$fffffa09.w        ; enable TiC
        bset.b    #5,$fffffa15.w        ; set interrupt mask B

Dzięki za kod. :) Zdążyłem już zrobić małe rozpoznanie i pod rejestr 1d należy wpisać wartość #$40, bo ustawiamy tylko 6 bit (div mode 50), a resztę zerujemy.

84

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

saulot napisał/a:

Co do włączania/modyfikacji TiC to zwykle maskuję wszystkie przerwania w sr, wyłączam TiC, ustawiam TiC i dopiero potem go włączam i przywracam sr.

Coś mniej więcej jak poniżej (ustawia TIC domyślnie na 200hz):

move.w    sr,-(sp)    ;save status register
        or.w    #$0700,sr    ;turn off all interupts

stop TiC:
bclr.b    #5,$fffffa15.w        ;set interrupt mask B

ustawianie TiC:
move.l    update,$114.w        ;slap interrupt
        move.b    #246,$fffffa21.w    ; set data
        ori.b     #80,$fffffa1b.w    ; div mode
        bset.b    #5,$fffffa09.w        ; enable TiC
        bset.b    #5,$fffffa15.w        ; set interrupt mask B

;enable interrupts
move.w       (sp)+,sr         ;restore Status Register

Hmm... rejestr $fffffa21 dotyczy timeraB, tak samo jak rejestr $fffffa1b :) Czyli de facto włączasz tylko timerC na ustawieniach standardowych :)

85

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

Dzięki za kod. :) Wychodzę z założenie, że im mniej, tym lepiej i na początku programu wyłączam sobie wszystko, co się tylko da. Później w razie konieczności włączam sobie kolejne klocki i timer C będzie mam nadzieję jednym z nich. :)

86

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

Dzięki. Wygląda obiecująco. :)
Edit: Kurde, też tylko vector pod timer podają. Nic to, trochę sam pokombinuję.

87

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

Hmmm... Coś podobnego udało mi się zrobić (i nie wiedzieć czemu nie gra ;)). Widzę, że ustawiasz swoją prockę pod timer C i zostawiasz domyślne systemowe ustawienia zegarów (200Hz). Chętnie podrążyłbym temat i zobaczył całą inicjalizację timera, masz coś takiego?

88

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

mkm napisał/a:

No tak, jeśli nie rozpakowałeś plików to pewnie to jest przyczyna f**k up'u.
A jesteś pewien, że chcesz to robić na Timer C? Mam taki kod i mogę go odkopać, ale... jeśli tylko tempo pozwala grać raz na ramkę to lepiej to podpiąć na vbl. No chyba, że musisz częsciej....

Mam już prockę pod vbl, ale chętnie jeszcze przepatrzyłbym kod pod timer C - próbowałem zrobić i coś mi nie działa. :( Chętnie w ramach przypominania/poznawania bebechów STeka zobaczę, jak to powinno wyglądać. Zresztą jak już się timer uruchomi, to można sobie stoper w grze zafundować... :P

89

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

Noo zawsze sobie pamięć na początku alokuje. :) Ale za to nie rozpakowałem pliku, więc chyba tutaj leży mój f**k up. :D Chętnie spojrzę na kod odgrywający muzę na timerze C, bo cosik nie możemy się ostatnio dogadać. :P

90

(18 odpowiedzi, napisanych Programowanie - 16/32bit)

No właśnie. Jakoś nie mogę ich odtworzyć.. :( Myślałem, że wystarczy tak, jak z przypadku snd zrobić jsr z offsetem 8 (oczywiście wcześniej inicjalizacja z offsetem 0) i wszystko zagra, a tu dupa. Macie gdzieś linka/kod, jak to powinno wyglądać?

91

(14 odpowiedzi, napisanych Programowanie - 16/32bit)

Dzięki za linka. :) Kurcze, u mnie z video counterem, to nawet base'a nie muszę ustawiać - zresztą pisał to też Cyprian. Muszę w takim razie jeszcze raz spojrzeć na coutera, bo może niepotrzebnie spinałem się z timerem - chociaż i tak go wykorzystuje, żeby sobie kilka palet kolorów na ekranie wyświetlać. :D Z tego, co się orientuję, to countera używa się do split screenów, tam trzeba wyświetlany adres zmieniać natychmiast. I ta świadomość natychmiastowości podmiany nie do końca mi przy podwójnym buforze pasuje ;) co nie oznacza, że jest błędna.

92

(14 odpowiedzi, napisanych Programowanie - 16/32bit)

Hospes napisał/a:

Tomek: Sorki za obsuwkę z grafą. Nagły atak spaw... znaczy się klientów. Jutro ślę na maila potrzebne pixelki.

Ok, spoko.. hscroll hula już w dwie strony, ma kupę kolorów i tylko grafy brakuje. :P

93

(14 odpowiedzi, napisanych Programowanie - 16/32bit)

OK. Widzę, że temat się rozwinął :D Po dwóch dniach rozgryzłem to już dosyć mocno, więc podzielę się obserwacjami :) Po pierwsze: ustawienie video base'a ma miejsce przy następnym VBL, video counter wprowadza zmiany natychmiast. Przy podwójnym buforze (jeśli się go wykorzystuję - ja tak robię), w grę wchodzi tylko Video Base. I teraz: zmiana $ff8265 z wartości niezerowej na zerową powoduje mignięcia, ponieważ zmiany wprowadzane są NATYCHMIAST, a nie przy kolejnym VBL. Więc jeśli zmieniacie to w vbl, będziecie mieć mignięcie, chyba że korzystacie z rejestrów video countera - ale to rozwali wam podwójny bufor. Rozwiązaniem jest zmiana tego rejestru PO wyświetleniu ekranu. Można do tego zastosować albo HBL i zliczyć sobie, kiedy skończy się wyświetlanie ekranu, albo zastosować timer b i też poczekać na koniec wyświetlania. Ja wybrałem timer, rejestr zmieniam w odpowiednim momencie i nie mam migotania :) Spróbujcie zrobić hscrolla na video base i z pixel shiftem, to zobaczycie, o co mi chodzi. :)

94

(14 odpowiedzi, napisanych Programowanie - 16/32bit)

Jest trochę zbugowany. :O Jeśli wykorzystujemy rejestr $ffff8265 (a musimy, żeby było płynnie i ładnie :P), to przy przejściu z wartości niezerowej na 0 można zauważyć parszywe migotanie ekranu. Sporo czasu zajęło mi, po pierwsze stwierdzenie, że ja czegoś nie spieprzyłem, a po drugie znalezienie odpowiedniego rozwiązania: należy zmieniać wartość rejestru PO wyświetleniu całego widocznego obrazu, czyli wykorzystać HBL lub odpowiednio skonfigurowany timer B. Może komuś przyda się ta wiedza kiedy zobaczy, że mu ekran w czasie vscrolla miga. :D

95

(9 odpowiedzi, napisanych Programowanie - 16/32bit)

Adam Klobukowski napisał/a:

Panowie, a w przypadku eor fill, nie da się Blitterem wypelnic polygona 1 operacją? odpada wówczes inicjalizacja per linie, ale dochodzi troche 'niechcianych' operacji, ale myślę że przy wypełnianiu kilku na raz, może wyjść na plus.

Nie do końca orientuję się, jak działa eor fill, ale pamiątaj, że obrys trójkąta trzeba wyrysować, trzeba pobrać poprzednią linię (to w blitterze zajmuje 8 taktów na 16 pikseli, a nie cztery jak przy wypełnianiu) i zeorować ją z aktualną, to z kolei zajmie albo 8 albo 12 taktów na 16 pikseli. Jak sobie podliczymy, to wcale już to tak dobrze nie wygląda. Chyba, że eor fill działa nie tak, jak napisałem? :(

96

(9 odpowiedzi, napisanych Programowanie - 16/32bit)

Cyprian napisał/a:

myślę że warto by to sprawdzić w praktyce. Z tego co widzę w w przypadku wariantu CPU i MOVEMów dla każdej linii dokonujesz jeszcze fline_m i lline_m które są dość kosztowne.

Fakt, pierwsza i ostatnia część linii - to koszmar. :P Przez ten kod można rzeczywiście upatrywać zwycięstwa blittera. Chociaż jeśli, to i tak z niewielką przewagą. Wypełnienie 16 pikseli w 4 planach na blitterze i motoroli zajmuje dokładnie tyle samo czasu: w przypadku blittera są to 4 cykle * 4 plany, w przypadku movema to 8 cykli * dwa rejestry, czyli też 16. :) Czyli o zwycięstwie zadecyduje z jednej strony narzut na inicjalizację blittera, a z drugiej narzut na odkodowanie movemów (6 movemów * 16 cykli + pierwsza i ostatnia linia).

Edit:
Policzyłem sobie:
Całkowity czas dla linii 320 pikseli na motoroli (według mojej procki), to: 2*96 + 5*(12 + 8*8) + (12+4*8) -> 616.
Dla blittera to: 320 + czas inicjalizacji na poszczególnych planach. Kurde, może jednak być trochę szybciej. Chyba, że o czymś zapomniałem, bo jakoś tak za szybko tutaj mi to wygląda... :P

Oczywiście wstępna inicjalizacja blittera zajmuje czas, więc chyba bez kodu się nie obejdzie... :D

97

(9 odpowiedzi, napisanych Programowanie - 16/32bit)

Cyprian napisał/a:

Myślę że dla cztero-bitplanowego fillera proporcje mogą ulec zmianie.
Jest jeszcze jedna niewykorzystana tutaj zaleta BLiTTERa. W czasie blittingu, CPU może wykonać jedną "długą" instrukcję, np rotacje, mnożenie/dzielenie itp. Z tego co widzę w kodzie, na każdy trójkąt przypadają trzy DIVSy. Być może dało by się je sprytnie przesunąć pod blitting.

Można pomyśleć o tablicy divsów, to by jeszcze trochę przyspieszyło kod. Jeśli chodzi o wstawianie instrukcji w czasie działania blittera, to chyba zadziała to tylko w przypadku trybu BLIT, czyli trybu dzielonego (ale mogę się mylić). No ciekawe, jak wypadłby blitter w 4 planowym fillerze, ale zaczynam odnosić wrażenie, że mógłby być wolniejszy od motorli (jak sobie spojrzycie na 4 bitplanowego fillera z kilku tematów wstecz, to do wypełniania używam tam movemów i przy długich liniach robię bodajże 64 piksele na jednym movie - to może być już dla blittera za dużo).

98

(9 odpowiedzi, napisanych Programowanie - 16/32bit)

Zdecydowanie. Motorola tym razem pokazała pazur. :P

99

(9 odpowiedzi, napisanych Programowanie - 16/32bit)

No i wielkie zaskoczenie! Motorola zrobiła to tak samo szybko, jak blitter! Wygląda na to, że blittera najlepiej używać do bardziej złożonych operacji z przesunięciami bitów, andami, xorami itd.

100

(22 odpowiedzi, napisanych Programowanie - 16/32bit)

Cyprian napisał/a:

i jeszcze coś mi wpadło do głowy. Czy faktycznie poniższa instrukcja jest potrzebna?

   move.w    d5,d3  ;4

"addq.w    #1,d3  ;4" robisz w obrębie Word a nie Long

Pamiętaj, że po tych operacjach w d3 jest trzymany i xCount i yCount.