Kwiecień 19, 2019, 09:07:11 *
Witamy, Gość. Zaloguj się lub zarejestruj.

Zaloguj się podając nazwę użytkownika, hasło i długość sesji
Aktualności:
Nowa strona główna  : http://www.emunes.pl
Zapraszamy do testowania !

Chat: http://chat.emunes.pl
Galeria cartów: http://carts.emunes.pl
 
   Strona główna   Pomoc Zaloguj się Rejestracja  

Reklama
Strony: [1]
  Drukuj  
Autor Wątek: PPU $2006 i $2007 - bezp. dostęp do PPU VRAM - JAK?  (Przeczytany 1858 razy)
0 użytkowników i 1 Gość przegląda ten wątek.
siudym
Gość
« : Listopad 27, 2014, 22:13:34 »

Mam problem ze zrozumieniem dojscia do komorek pamieci PPU VRAM. Ze wzgledu, ze CPU i PPU maja
osobne magistrale pamieci, aby uzyskac dostep do VRAM trzeba kozystac z rejestrow $2006 i $2007.
Nie moge logicznie rozgryzc w jakis sposob mozna bezposrednio taki dostep miec.

Chodzi mi dokladnie o mozliwosc plynnej podmiany TILESow/Grafiki tla. Przykladowo w grafice tla mam
narysowany kwiatek, ale chcialbym aby listki kwiata krecili sie dookola tworzac animacje. Czy musze
podmienic go na TILES SPR czy mozna to zrobic bezposrednio na komorke VRAM (w jednym miejscu tla
bedzie jeden lub wiecej TILESow plynnie podmieniane czyli zrobiona petla, ktora na ekranie wyswietli
plynnie krecacego sie kwiatka).


Przykladowy CHR BGR - TILE'sy ktore beda animowane w TLE to nr #$10 do #$18.

Zapisane
Dizzy9
Nadworny programista.
Kapitan
****
Offline Offline

Wiadomości: 351



WWW
« Odpowiedz #1 : Listopad 28, 2014, 18:40:57 »

Są trzy główne sposoby:
1.Używanie CHR RAM
  Metoda bardzo ograniczona. Możesz to robić tylko gdy ekran jest wyłączony (lub w czasie NMI). Podmieniasz wtedy grafikę w VRAM.
2.Używanie mappera z kilkoma bankami CHR ROM
  Podmiana jest błyskawiczna, za podmianę odpowiadają rejestry odpowiednie dla różnych mapperów.
3.Podmiana tilesów na Name Table
 Dość trudna metoda, ale jedyna możliwość jeśli używasz NROM+chr rom.

Nie ma lepszej metody, to czy jest lepsza zależy od designu gry i mapperu na jaki grę robisz.
Zapisane

siudym
Gość
« Odpowiedz #2 : Listopad 28, 2014, 19:50:07 »

Wlasnie zaintersowala mnie podmiana tilesow na NameTable. Domyslam sie, ze problematyczna jest sprawa dostepu do VRAM konsoli? bo WRAM konsoli wiadomo mamy dostep bezposrednio, ale VRAM tylko przez dwa? rejestry.

Rozumiem, ze jest ciezko, ale czy znasz ten sposob podmiany danych w NameTable juz bedacej skopiowana w VRAM konsoli??
« Ostatnia zmiana: Listopad 28, 2014, 19:55:50 wysłane przez siudym » Zapisane
Dizzy9
Nadworny programista.
Kapitan
****
Offline Offline

Wiadomości: 351



WWW
« Odpowiedz #3 : Listopad 28, 2014, 19:58:35 »

Problematyczna sprawa, ponieważ jeśli masz 100 kwiatków na ekranie, to musisz podmienić 100 patternów (zakładając że rozmiar kwiatka to jeden pattern).
Żeby wypisać coś na Name Table, ustawiasz PPUADDR (rejestr $2006) na miejsce gdzie jest kwiatek i zapisujesz numer tilesa poprzez PPUDATA (rejestr $2007)
Zakładając że kwiatek znajduje się w lewym górnym rogu na NT 0:
Kod:
lda #$20
 sta $2006
 lda #$00
 sta $2006

 lda #$10
 sta $2007
Metoda niewygodna, bo byś musiał mieć w RAMie (lub nawet i ROMie) jakąś tablicę z adresami dla PPU dla każdego kwiatka....
Zapisane

siudym
Gość
« Odpowiedz #4 : Listopad 28, 2014, 20:12:50 »

Tzn z kwiatkiem byl przyklad. I nie chodzi mi o 100 kwiatow, ale jakis jeden element w tle, ktory da sie animowac. Nie chodzi mi o duze animacje, ale aby w tle jeden tiles VRAM migotal na zasadzie pętli tilesow BGR nr. 10 do 18.

Nie wiem czy mozna zrobic taka petle uzywajac:

Kod:
lda #$20
 sta $2006
 lda #$00
 sta $2006

 lda #$10
 sta $2007

Moze tak da sie raz podmienic, ale czy petla? np:

lda #$20
 sta $2006
 lda #$00
 sta $2006


 lda #$10
 sta $2007


Kod:
bgranm:
LDA $2007  ;zakladajac, ze wczesniej juz zapisana jest wartosc 10

INC $2007
cmp #$18
BNE END
LDA #$10
STA $2007

END:

RTS

To raczej nie zadziala. Ale za duzo mysle...
« Ostatnia zmiana: Listopad 28, 2014, 20:24:11 wysłane przez siudym » Zapisane
Dizzy9
Nadworny programista.
Kapitan
****
Offline Offline

Wiadomości: 351



WWW
« Odpowiedz #5 : Listopad 28, 2014, 20:43:24 »

Nie możesz tak.
Odczytanie PPUDATA zwiększy PPUADDR o 1, użycie Inc PPUDATA większy adres o 3 zanim liczby w ppu zostaną podmienione.
No i musisz, musisz podać adres dla PPUADDR. No i co dokładnie chodzi z tą pętlą? Żeby tiles był animowany (jak pisałeś, zakładamy ze jest tylko 1) to wystarczy jeden zapis. Żeby była animacja, to ten zapis musi występować co ileś klatek, ewentualnie co każdą klatkę...ale nie kilka zapisów naraz.
Stwórz dwa liczniki. Jeden an $0E drugi na $0F. $0E to ilość klatek miedzy podmianą tilesa. $0F to ID tilesa do podmianki.
Kod:
lda $2002   ;Zresetuj stan PPUADDR

 lda #$20
 sta $2006
 lda #$20
 sta $2006  ;Pierwszy widoczny tiles na NTSC

 lda $0F
 sta $2007  ;Zapisz id tilesa do podmiany

 lda $0E
 sec
 sbc #$1
 sta $0E ;Zmniejsz ilosć klatek do odczekania o 1
 
 bcc Resetuj_licznik

 jmp kontynuuj ;Nie trzeba uzupełniać ilości klatek, kontynuuj

Resetuj_licznik:

 lda #$05
 sta $0E ;Uzupełnij ilość klatek do odczekania zanim nastąpi podmiana tilesa.
 
 lda $0F ;Zwiększ numer wypuisywanego tilesa
 clc
 adc #$1
 sta $0F
 
 cmp #$18
 bne kontynuuj ;18 tiles to nie jest tiles należący do animacji.
 
 lda #$10
 sta $0F ;Zresetuj ID tilesa do podmiany

kontynuuj:
 (Tutaj twój dalszy kod)
Powyższy kod należy umieścić najlepiej w NMI, przed aktualizacją rejestrów $2005. Kilka początkowych klatek będą mieć złą animację, żeby temu zapobiec, zapisz 0x10 do $0F
Zapisane

siudym
Gość
« Odpowiedz #6 : Grudzień 01, 2014, 17:20:16 »

Jakis czas temu wpadl mi do glowy sposob na kopiowanie danych z RAM do PPU VRAM. Na zasadzie podobnej jaka dzieje sie z OAM SPR RAM (Pamiec RAM na drugiej stronie czyli $0200-02FF jest kopiowana do OAM w PPU - 256 byte). Niestety pomysl opieral sie na skopiowaniu jednoczesnie w czasie jednego NMI calego kilobajta ramu - co jest niewykonalne, bo czas ten (jedno nmi) umozliwia na skopiowanie max. kolo 280 bajtow.

Jednak nieco doczytalem i mozna zrobic to na raty. Kopiowac 256 bajtowe czesci VRAM. W zalaczniku przykladowy kod, podzielony NAMETABLE na 4 czesci, ladowanie osobno 8-bitowe tych czesci. Teraz tylko w jaki sposob to zrobic? Pamiec RAM przeznaczona na kopie VRAM to $0400-07FF (4 czesci: 0400-04FF, 0500-05FF, 0600-06FF oraz 0700-07FF)

Wczesniej bedzie trzeba zapewne zapisac kopie plikow NT przed praca glownego programu do $0400-07FF, ale to jakis problem nie jest.

Problem jak rozwiazac ciagle zgrywanie tej pamieci ponownie do VRAM w pierwsze 1024 NT0 ?


https://www.dropbox.com/s/g09bymgci2hl0ar/nametable8bitonly_vramshadow.zip?dl=0



Probowalem zrobic cos takiego (w kodzie w linku tych zmian nie ma)
- zmiana LoadNT1, LoadNT2 etc zmienilem na:

Kod:
LoadNT1:
LDX #$00
LoadNT1Loop:
LDA NameTable1,x
STA $0400,x
        INX
CPX #$00
BNE LoadNT1Loop
RTS

- potem juz w NMI:

Kod:
CopyWtoV1:
LDA #$20 ;load 256byte NT to 2000
STA $2006
LDA #$00
STA $2006

LDX #$00
LoadNT1LoopX:
LDA $0400,x
STA $2007
INX
CPX #$00
BNE LoadNT1LoopX
RTS


EDIT:

Dziala czesciowo. W sumie tak jak przywidywalem. Czas na zaladowanie to na styk jedna czesc NT 256 bytes.

« Ostatnia zmiana: Grudzień 01, 2014, 21:50:11 wysłane przez siudym » Zapisane
Dizzy9
Nadworny programista.
Kapitan
****
Offline Offline

Wiadomości: 351



WWW
« Odpowiedz #7 : Grudzień 01, 2014, 21:49:27 »

Cytuj
OAM SPR RAM (Pamiec RAM na drugiej stronie czyli $0200-02FF
Kopia OAM może być na każdej stronie pamięci RAM. $200-$2FF jest po prostu najczęściej używane przez programistów. Błędem jest jednak myśleć że kopia robocza OAM może być tylko w tym przedziale. np. Chip & Dales 2 używa do tego celu $600-$6FF.
Cytuj
Problem jak rozwiazac ciagle zgrywanie tej pamieci ponownie do VRAM w pierwsze 1024 NT0 ?
Możesz to zrobić na kilka sposobów.
Można zrobić aktualizację każdej części na zmianę. Tzn. w pierwszej klatce pierwsza część, w drugiej kolejna itp.
Możesz też wyłączyć część ekranu poprzez synchronizację z ppu (jakimkolwiek sposobem) i używając ekstra czasu zrobić aktualizację której części.
Możesz też przykleić naklejkę "ta gra nie działa w NTSC" i robić na PAL. Gry w regionie PAL mają NMI dłuższe o 50 scanline więcej niż NTSC!
Ale najlepszym rozwiązaniem byłoby zastosowanie bufferów i zapisywanie do nich kiedy nadejdzie taka potrzeba.
Buffery się stosuje by podmieniać części ekranu kiedy jest taka potrzeba i tam gdzie trzeba.
Przerobiłem Twój przykład by używał szybko napisanego kodu dla bufferu. Strzałką w prawo zmienisz jeden tiles na początku strefy drugiej. Strzałką w lewo zmienisz 4 tilesy. Strzałką w górę wypiszesz moją ksywkę (używając do tego odczytywania buffera z ROMu).

Zapisane

siudym
Gość
« Odpowiedz #8 : Grudzień 01, 2014, 21:50:40 »

Edytowalem post jak pisales Smile Dzieki za info, potem ogarne nowe wieści z linka  Roll Eyes

Juz dokoncze tu. Jak widac wyzej dziala, ale laduje jedne 256 byte NT. Nie starcza juz czasu nawet na zaladowanie ATTR table 64bytes.

Tu link z inna wersja, gdzie juz zaladowalem najpierw do RAM NT, a potem z RAM do VRAM przez rejestry 2006 i 2007:
https://www.dropbox.com/s/j5gpipz1n88958c/vramshadownt.zip?dl=0

Gdy zaladuje dodatkowo samo ATTR table - siada wszystko:

To w PAL.


A w NTSC jest mniej czasu miedzy NMI i w tym trybie juz krzaczory Smile


EDIT:
Probowalem po swojemu i nawet sie udalo. Test ROM - wciskac A aby animowac kilka tilesow BGR
https://www.dropbox.com/s/nns71yijulsca8p/animbgr.nes?dl=0

Zrobiony duplikat zaladowanych czesci NT oraz zrobiona kopia do $0400-07FF. Dodatkowo w NMI podmieniana jest non-stop 0400-04FF. Na tych komorkach pamieci animowane tilesy BGR.
« Ostatnia zmiana: Grudzień 02, 2014, 22:03:25 wysłane przez siudym » Zapisane
Strony: [1]
  Drukuj  
 
Skocz do:  

Działa na MySQL Działa na PHP Powered by SMF 1.1.11 | SMF © 2006-2008, Simple Machines LLC Prawidłowy XHTML 1.0! Prawidłowy CSS!
Strona wygenerowana w 0.057 sekund z 19 zapytaniami.