1 Ostatnio edytowany przez nosty (2011-01-10 11:06:30)

Czy to jest wykonalne?
Bo spotkalem sie z roznymi opiniami. Chodzi mi o to czy HPOSP0 (pozycja pozioma Player0 - $D000) jest odczytywany przez GTIA raz na linie (przy DLI) czy czesciej? A moze to jest cien a jest jakis rejestr sprzetowy odczytywany na biezaco, jak w przypadku rejestrow odpowiedzialnych za kolory ducha?

Zrobilem eksperyment. Duch ma postac dwoch "buziek" - jednej pod drugą.
Napisalem w Atalanie najprostszą mozliwą petle zmieniająca pozycje ducha z 90 na 100 i odwrotnie tak czesto jak sie da.
W asemblerze, po lekkich recznych korektach kod wyglada tak:

pozycja equ 130
player__x equ 53248

_lbl7:
;### int.atl(97)    if pozycja = 100 then pozycja = 50
   lda #100
   cmp pozycja
   jne _lbl5
   lda #50
   sta pozycja
;### int.atl(98)    else pozycja = 90
   jmp _lbl6
_lbl5:
   lda #90
   sta pozycja
_lbl6:
;### int.atl(99)    player(0).x = pozycja
   sta player__x
_lbl3:
   jmp _lbl7

Zalaczam XEX i screen.

Sprawdzalem pod emulatorem robiac "stopklatke" i ani razu nie zaobserwowalem zeby ktorakolwiek z linii ducha byla narysowana podwojnie w pozycji 90 i 100 jednoczesnie.
Wynikaloby z tego ze multiplikacja przez zmiane rejestru HPOSP0 nie jest mozliwa.

Kod jest na tyle krotki ze moim zdaniem powinien wykonac sie z powodzeniem kilka razy w ciagu jednej linii (byc moze zreszta tak sie dzieje i dlatego przeplot nie jest dokladny tylko nieraz rysuja sie dwie kolejne linie w jednej pozycji bo pozycja zmienia sie z 90 na 100 i znow na 90 zanim rejestr zostanie odczytany).

Dziwi mnie troche zachowanie emulatora Atari (Atari800Win 4.0 beta 7). Odpalcie i poczekajcie okolo 10 sekund - mruganie duszkow nagle zwalnia do jednego przeskoku co pare sekund. O_o Ale to chyba jakis blad emulatora po prostu...

Post's attachments

int.zip 1.83 kb, liczba pobrań: 10 (od 2011-01-10) 

Tylko zalogowani mogą pobierać załączniki.

2

a próbowałeś w większych odstępach od siebie te buźki rysować?

3

Ale pytasz, czy jest to możliwe w GTIA, czy w emulatorach? :D

Hitler, Stalin, totalniak, SSman, NKWDzista, kaczor dyktator, za długo byłem w ChRL, wypowiadam się afektywnie.

4 Ostatnio edytowany przez nosty (2011-01-10 11:30:55)

xan napisał/a:

a próbowałeś w większych odstępach od siebie te buźki rysować?

Sprobowalem przed chwila. Zmiana miedzy 50 a 200.
Faktycznie niektore linie rysuja sie teraz podwojnie a niektore nie rysuja sie wcale! Zalaczam screena.
Czyli da sie narysowac ducha w 2 pozycjach w tej samej linii...

Wynikaloby z tego ze trzeba postepowac jak przy zmianie kolorow grafiki w srodku linii? Czyli poczekac na narysowanie lewego ducha i wtedy dopiero zmienic pozycje i bede mial dwa niemrugajace duchy w tej samej linii? :)

Jaka moze byc najmniejsza odleglosc ducha od jego kopii zeby to sie udalo?

Sprobuje cos takiego zakodowac.

epi napisał/a:

Ale pytasz, czy jest to możliwe w GTIA, czy w emulatorach? :D

A to naprawde az taka roznica na tym poziomie? Myslalem ze emulatory (przynajmniej A800win) sa juz prawie perfekcyjne... Sie tak dziwie, bo znam pewnego programiste Atari, z naprawde scislej czolowki, ktory nie ma real Atari i koduje swoje najlepsze gry na emulatorach ;)

Post's attachments

atari001.png 1.34 kb, nikt jeszcze nie pobierał tego pliku. 

Tylko zalogowani mogą pobierać załączniki.

5

>>link<<

6 Ostatnio edytowany przez mono (2011-01-10 12:41:33)

Nosty - musisz zrozumieć, jak sprajty są rysowane na ekranie, żeby je multiplikować. Właściwie całą zasadę da się ująć w kilku zdaniach:

1. GTIA decyduje NA BIEŻĄCO o narysowaniu sprajta na podstawie zawartości rejestru HPOSPx/Mx.
2. Odrysowanie zawartości sprajta następuje na podstawie zawartości rejestru GRAFPx/M, SIZEPx/M, COLPMx, GTIACTL (priorytet).
3. Rejestr GRAFPx/Mx może być wypełniany przez DMA raz na linię (jest to dyktowane specyfiką pracy ANTICa) jeśli jest włączone w DMACTL (VBLKD przepisuje tam wartość z DMACTLS oczywiście jeśli jest włączone) - dane są pobierane z pamięci odpowiednio do stanu rejestrów PMBASE i VDELAY oraz rozdzielczości liniowej ustawionej w DMACTL.

Nikt nie zabrania zapisywania dowolnego rejestru GTIA w dowolnym czasie. Z ANTICem jest nieco inaczej - rejestry możesz zapisywać dowolnie, ale on sam pobiera dane w określonych chwilach.

Widoczność sprajtów na ekranie jest konfigurowana za pomocą PMCNTL.

Najprostsza multiplikacja sprajta wymaga jedynie szybkiej zmiany rejestru HPOSPx/Mx. Jeśli chcesz mieć inną treść to musisz zapisać GRAFPx/M, jeśli rozmiar to SIZEPx/M, kolor to COLPMx, itd.

Pożegnaj się z jakimikolwiek manipulacjami w pierwszej (lub ostatniej? - nie pamiętam) linii każdego wiersza trybu tekstowego, bo ANTIC bierze wtedy dane pamięci ekranu i kształtu sprajtów do bufora. W trybach graficznych tego problemu nie ma.

Edit: Drobiazgi.

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

7

gorgh napisał/a:

>>link<<

Dzieki.

"z moich exp. wynika ,ze przy DLI wywolywanym nie od poczatku ale od srodka ekranu mozna powielic duszka nawet 6 krotnie(bez zmiany ksztaltu i zadnych innych operacji), badz 3 krotnie przy zmianie ksztaltu wszystkich trzech i koloru w przypadku 2( 2 duchy w DLI i 1 w petli programu)"

Co oznacza "przy DLI wywolywanym nie od poczatku ale od srodka ekranu "? Myslalem ze DLI jest przerwaniem wywolywanym zawsze w tym samym momencie bo jest zwiazana z fizyczną budowa ekranu (powrotem plamki elektronowej?)

I jeszcze jedno pytanie z tym zwiazane:
To czy w danej linii ma byc przerwanie DLI czy nie, definiuje sie w DL, ale jesli mam tryb znakowy (np 0) to na jedna linie znakową przypada 8 linii ekranu. Czyli jak ustawie dla tej linii DLI to bedzi ono wykonywane 8 razy - dla kazdej linii ekranu wchodzacej w sklad linii znakowej?

Probowalem napisac proste multiplikowanie duszka w poziomie ale na razie z marnym skutkiem :/

8 Ostatnio edytowany przez mono (2011-01-10 13:12:11)

Przerwanie w trybie tekstowym wykonuje się w ostatniej linii wiersza.

"DLI wywołane od środka linii" to uproszczenie - procedura wywołuje się jak zawsze, ale na jej początku znajduje się opóźnienie.

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

9 Ostatnio edytowany przez gorgh (2011-01-10 13:30:02)

nosty napisał/a:

Co oznacza "przy DLI wywolywanym nie od poczatku ale od srodka ekranu "? Myslalem ze DLI jest przerwaniem wywolywanym zawsze w tym samym momencie bo jest zwiazana z fizyczną budowa ekranu (powrotem plamki elektronowej?)

To znaczy bez czekania na synchronizację poziomą ( sta WSYNC), przerwanie działa nie od końca linii ale trochę wcześniej/później (zależy jak na to patrzeć).[edit]

nosty napisał/a:

I jeszcze jedno pytanie z tym zwiazane:
To czy w danej linii ma byc przerwanie DLI czy nie, definiuje sie w DL, ale jesli mam tryb znakowy (np 0) to na jedna linie znakową przypada 8 linii ekranu. Czyli jak ustawie dla tej linii DLI to bedzi ono wykonywane 8 razy - dla kazdej linii ekranu wchodzacej w sklad linii znakowej?

What Mono said. Aby mieć Dli w każdej linii po prostu nie wychodzisz z przerwania aż do ostatniej linii wiersza. Oczywiście oprócz 1 linii w trybie znakowym.

10

popatrz sobie jeszcze tu:
http://spiflash.org/atari/DMAV.zip
http://spiflash.org/atari/antic-dma.zip

klawisz z robi zoom
patrzysz na cykle pracy cpu/antic, fecze dli, pmg i refresze
logi - electron
viewer - ja

przechodze na tumiwisizm

11

A spiflash.org leży, czy mi się zdaje?

Hitler, Stalin, totalniak, SSman, NKWDzista, kaczor dyktator, za długo byłem w ChRL, wypowiadam się afektywnie.

12

u mnie spiflash.org działa. łącze od UPC.

13

"Aby mieć Dli w każdej linii po prostu nie wychodzisz z przerwania aż do ostatniej linii wiersza. Oczywiście oprócz 1 linii w trybie znakowym." - to nie da przerwania co linie. choc efektywnie przerwanie "bedzie obslugiwane" dluzej, wiec bedzie sie rozciagac rowniez na inne linie.

nosty: uzyskujesz to przez takie "docyklowanie" by procka wykonywala sie w trakcie powrotu plamki z konca jednej linii do poczatku kolejnej. oczywiscie moze sie tez wykonywac "w trakcie" punktowania linii. po prostu jej wykonywanie sie musi trwac przez rozciaglasc ilosci linii znaku w danym trybie tekstowym.

The UNIX Guru`s view of Sex:
unzip; strip; touch; finger; mount; fsck; more; yes; umount; sleep

14

Nieważne, już działa.

Hitler, Stalin, totalniak, SSman, NKWDzista, kaczor dyktator, za długo byłem w ChRL, wypowiadam się afektywnie.

15

jellonek napisał/a:

"Aby mieć Dli w każdej linii po prostu nie wychodzisz z przerwania aż do ostatniej linii wiersza. Oczywiście oprócz 1 linii w trybie znakowym." - to nie da przerwania co linie. choc efektywnie przerwanie "bedzie obslugiwane" dluzej, wiec bedzie sie rozciagac rowniez na inne linie.

nosty: uzyskujesz to przez takie "docyklowanie" by procka wykonywala sie w trakcie powrotu plamki z konca jednej linii do poczatku kolejnej. oczywiscie moze sie tez wykonywac "w trakcie" punktowania linii. po prostu jej wykonywanie sie musi trwac przez rozciaglasc ilosci linii znaku w danym trybie tekstowym.

Rozumiem i nie rozumiem :) Czyli moge sobie przeciagnąc czas trwania przerwania DLI na czas rysowania kilku linii (ekranowych - pixelowych) po prostu nie wychodząc z procedury?
Wszedzie wczesniej czytalem ze na przerwaniach DLI niewiele mozna zrobic bo jest tam tylko czas na kilkadziesiat cykli procesora itp.  A tu piszecie ze moge przeciagac to przerwanie ile chce... tzn az plamka narysuje wszystkie linie znakow?

Ale w sumie nie o to chodzi zeby przerwanie DLI bylo jak najdluzsze. Pytalem o to czy przerwanie jest w kazdej linii obrazu (pixelowej) zeby miec jakis znacznik od ktorego glowny program moze odliczac takty aby w odpowiednim momencie przestawic pozycje X duszka aby go zmultiplikowac.
Nie wiem czy pisze zrozumiale. Zeby zmultiplikowac duszka trzeba zmienic jego pozycje X w kazdej linii obrazu (pixelowej). W tej sytuacji, gdyby miec przerwanie DLI w kazedej linii mozna by w nim bo ja wiem, zerowac jakis znacznik, zeby bylo wiadomo ze zaczela sie nowa linia i mozna liczyc takty.
Ale widze ze w trybie tekstowym jest to niemozliwe, wiec multiplikowanie w nim duszka w poziomie jest pewnie praktycznie niewykonalne z powodu trudnosci obliczeniowych.
Musze sie "przesiasc" na analogiczny tryb graficzny.

Dzieki wszystim za wyjsnienia. Postaram sie tego nie zmarnowac. Choc chyba zaczne od opanowania pojedynczych duszkow, potem przejde do multiplikowania w pionie a dopiero na koncu do powielania w poziomie ;)

16

Jeszcze jedno pytanie, bo wzielo mnie na wieczorne eksperymenty :D

Ustawilem w rejestrze DMACTL wylacznie DMA dla DL i bity 0,1  = brak obrazu. Ekran byl czarny ale duszki mi sie wyswietlily!

Czy dobrze rozumiem, ze mozna wyobrazic sobie gre, ktora bedzie dzialac wylacznie na duszkach (GTIA) na czarnym tle, przy calkowicie wylaczonym ANTIC'u? :)

17 Ostatnio edytowany przez mono (2011-01-10 21:53:38)

A co wpisałeś do PMGCTL? Jeśli ustawiłeś tam wyświetlanie sprajtów, to GTIA będzie rysowało na ekranie zawartość rejestrów GRAFPx/M. Bity w DMACTL ustawiają tylko DMA ANTICa dla sprajtów (czyli automatyczne przepisywanie zawartości kawałka pamięci do rejestrów GRAFPx/M co linię/dwie).

Edit: Właśnie dzięki temu możliwa jest multiplikacja sprajtów.

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

18

mozesz przedluzyc czas trwania procedury obslugi przerwania, samego przerwania nie przedluzysz, bo to impuls ;)
nie zupelnie mozesz "ile chcesz" przeciagac, bo jesli pozwolisz by procedura obslugi przerwania zostala wywolana zanim sie skonczy wczesniejsza - latwo mozesz "zadeptac" stos ;)

nie, przerwanie jest na jedna linie antica, czyli w przypadku gr.0 raz na osiem linii pikselowych. przerwanie "nastepuje", to jest tylko moment wywolania procedury - ile trwa sama procedura - zalezy od tego ile w nia kodu upchniesz. pamietaj tylko by sie konczyla przed wywolaniem kolejnego przerwania, np. w kolejnej linii znakowej, czy tez np. za pol ekranu.

ps. cyklowanie i modyfikacja rej. sprzetowych jest tak samo mozliwe (i tak samo trudne) w trybie tekstowym jak w trybie graficznym...

The UNIX Guru`s view of Sex:
unzip; strip; touch; finger; mount; fsck; more; yes; umount; sleep

19

nosty napisał/a:

Czy dobrze rozumiem, ze mozna wyobrazic sobie gre, ktora bedzie dzialac wylacznie na duszkach (GTIA) na czarnym tle, przy calkowicie wylaczonym ANTIC'u? :)

Można sobie wyobrazić, acz ANTIC nigdy nie jest całkowicie "wyłączony", pewnie będzie trochę przeszkadzał (objaw: poziome rozciągnięcie obrazu z lewej strony).

KMK
? HEX$(6670358)

20 Ostatnio edytowany przez nosty (2011-01-10 22:21:39)

mono napisał/a:

A co wpisałeś do PMGCTL? Jeśli ustawiłeś tam wyświetlanie sprajtów, to GTIA będzie rysowało na ekranie zawartość rejestrów GRAFPx/M. Bity w DMACTL ustawiają tylko DMA ANTICa dla sprajtów (czyli automatyczne przepisywanie zawartości kawałka pamięci do rejestrów GRAFPx/M co linię/dwie).

Edit: Właśnie dzięki temu możliwa jest multiplikacja sprajtów.

Nic nie zmienialem w PMGCTL. Tzn oczywiscie bylo ustawione wyswietlanie sprajtow. Chcialem tylko wylaczyc Antica i zobaczyc co bedzie.

"Bity w DMACTL ustawiają tylko DMA ANTICa dla sprajtów" - czyli jak wygasilem bit 5 i bity 0 i 1 to Antic jednak dziala, a wylaczylem tylko "DMA ANTICa dla sprajtów"?  Wydawalo mi sie ze bit 5 wylacza DMA dla calego Antica.

Myslalem ze sprajty sa na GTIA i sa niezalezne od Antica - czyli powinny dzialac nawet jesli ten jest wylaczony. Choc to problem troche akademicki...

21

jellonek napisał/a:

ps. cyklowanie i modyfikacja rej. sprzetowych jest tak samo mozliwe (i tak samo trudne) w trybie tekstowym jak w trybie graficznym...

Teraz mnie zbiles z tropu.
A skad w trybie tekstowym kod "wie", ze wlasnie zaczelo sie rysowanie nowej linii obrazu (w sensie pixelowym nie tekstowym)? Musi wiedziec zeby policzyc takty i w odopowiednim momencie przesunac pozycje ducha w prawo.
A potem trzeba wiedziec kiedy linia jest juz narysowana i cofnac pozycje ducha znow w lewo.
Sadzilem, ze przerwanie DLI w kazdej linii pixelowej (czyli np w trybie tekstowym) znakomicie by to ulatwilo.
Jak to zrobic kiedy przerwanie jest np. tylko raz na 8 linii? Jest jakis rejestr ktory wskazuje ze plamka elektronow wlasnie zaczyna rysowac kolejna linie, czy jak?

22

nosty
antik adresuje szyne danych, zauwaz, ze adresy bazowe dla sprajtow  sa w antiku, a nie w gtia
i tak jak wylaczysz dma dla dl, to wciaz mozesz miec dma dla pmg
polega to na tym, ze antik liczy sobie do odpowiedniego miejsca linii rastra (mimo ze nie ma obrazu), na an''ach masz caly czas stan "horizontal blank" i daje halt i wystawia odpowiedni adres na magistrale
gtia lapie ze jest halt i ze rejestry hcount maja odpowiednie wartosci by szukac danych do wpisania do rejestrow ksztaltu duchow, wiec bierze sobie dane z szyny danych i zapisuje do swojego rejestru
teraz jak spojrzysz sobie na te chartsy ktore zrobil elektron to zobaczysz tam taki pattern
pierwszy fecz pmg - koniec lini
kolejne fecze sa przeplatane feczami dla dl - kazdy taki fecz, to halt idacy w dol, wiec zatrzymanie cpu i zwolnienie szyny
nie wazne czy wylaczyles dma dla dl czy nie, gtia chce dostac konkretna ilosc haltow dla konkretnych graczy/pociskow
wiec antik i tak zatrzyma ci cpu dla tych wszystkich slotow - nie wazne czy bedzie cos pobieral czy nie - inaczej gtia zglupieje
dodatkowo masz jeszcze cykle refreszu ramu - jakbys sie staral to ich nie wylaczysz

przechodze na tumiwisizm

23

Tak więc możesz sobie włączyć rysowanie sprajtów przez GTIA i DMA dla sprajtów w ANTICu a wyłączyć DMA dla dlisty, bo można tym sterować osobno.
Skąd kod wie, że jest rysowana linia? Bo wystąpiło przerwania DLI (o ile ustawiłeś je w odpowiedniej linii ekranu) i właśnie CPU w nie wszedł. To którą linię aktualnie rysuje ANTIC/GTIA masz w VCOUNT.
Poziomej pozycji nie ma, ale nietrudno ją wyliczyć (w pamięci) wiedząc w którym cyklu koloru zgłaszane są przerwania DLI i ile cykli koloru trwa jeden takt CPU (trwa 2). Cykl koloru to szerokość jednego piksela w trybie OS 15 (2 pikseli w OS 8).
Tak więc jeśli w przerwaniu masz instrukcje:

pha
pla
rti

to możesz na początek założyć, że Twoja procedura wykona się w 7+3+4+7=21 cyklach CPU a więc w czasie rysowania 42 pikseli GR.15.
7 pierwszych taktów to przyjęcie przerwania przez CPU (odłożenie adresu powrotu + rejestru znaczników na stos, i skok pod adres zawarty w NMIVEC), 3 cykle to pha, 4 cykle to pla, 7 cykli to rti. No i tak dalej.
Ponieważ NMI są obsługiwane przez OS to opóźnienie wynikłe z wykonania rozpoznania źródła przerwania i skoku do wektora DLIV wyglądające tak:

  bit NMIST
  bpl jvblk
  jmp (dliv)
jvblk:
  ... ;to nas nie interesuje
  

zabiera jeszcze 4+2+5=11 cykli CPU.

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

24

nosty napisał/a:

Myslalem ze emulatory (przynajmniej A800win) sa juz prawie perfekcyjne... Sie tak dziwie, bo znam pewnego programiste Atari, z naprawde scislej czolowki, ktory nie ma real Atari i koduje swoje najlepsze gry na emulatorach :wink:

Atari800WinPLus? Kulą w płot żeś trafił, jest to najmniej dokładny emulator z dostępnych. Przesiądź się na bardzo dokładną Altirrę.

A8CAS - narzędzie do 100% archiwizacji kaset Atari

25

Candle napisał/a:

...taki pattern: pierwszy fecz pmg - koniec lini, kolejne fecze sa przeplatane feczami dla dl - kazdy taki fecz, to halt idacy w dol, wiec zatrzymanie cpu i zwolnienie szyny nie wazne czy wylaczyles dma dla dl czy nie, gtia chce dostac konkretna ilosc haltow ....

To lepsze od "główka karbowana zawleczki przetyczki wąsa zamka osi wyrzutnika" (c) jer :)