Gruzińskie Noce 02, czyli Nerdy Nights po polsku
Gruzińskie Noce 02, czyli Nerdy Nights po polsku
« dnia: Maj 25, 2016, 13:13:12 »
Tydzień 2: Architektura NES i troszkę o grafice

Architektura NES

KB - Kilobajt to Kilo bajtów, czyli tysiąc. No ciut ponad: 1KB = 1024 B. Komputer liczy na dwójkach, stąd nierówna końcówka - 2^10 = 1024. Co innego znaczy Kb, a co innego KB. Kb to kilobity (mniejsze). Dzieląc Kb (bity, czyli mniejsze) przez 8 o trzymasz tyle samo w jednostce KB (bajty, większe). Tak jak w prędkości internetu: możesz mieć łącze 16Mb/s które jest równe 2MB/s.
 
ROM - Read Only Memory,  przetrzymuje dane, które nie mogą być zmieniane. Tu zapisany jest kod gry albo grafika.

RAM - Random Access Memory, przetrzymuje dane które mogą być odczytywane i zapisywane.  Po odłączeniu napięcia chip jest opróżniany, by podtrzymać jego treść można użyć baterii.

PRG - Program memory, pamięć na kod gry.

CHR - Character memory, pamięć na grafikę

CPU - Central Processing Unit, główny procesor

PPU - Picture Processing Unit, chip graficzny

APU - Audio Processing Unit, chip audio znajdujący się wewnątrz CPU


Opis systemu

NES ma w sobie CPU oparty na procesorze 6502 z APU i obsługą kontrolera na jednym chipie oraz PPU odpowiedzialnym za grafikę na osobnym chipie. Twój kod odczytywany jest przez CPU i wysyła rozkazy do APU i PPU. Famiklony NOAC (NES On A Chip) jak większość słabych pegazusów i wszystkie "nowe" mają wszystko to w jednym zamknięte (nazywany glutem, ptasim mleczkiem itp.)




Są tylko 2KB RAMu dla CPU do przechowywania zmiennych oraz drugie 2KB dla PPU do utrzymywania dwóch ekranów grafiki tła. Niektóre carty rozszerzają pamięć CPU Working RAMem. Jeśli trzeba zapisać stan gry odbywa się to właśnie na WRAMie, którego stan utrzymuje bateria w cartridge'u. Mało które carty rozszerzają pamięć PPU do utrzymania czterech ekranów tła na raz - nie jest to stosowane często. Przez resztę tutoriala nie będziemy używać ani WRAMu ani czteroekranowego RAMu.

Każdy cart NESowy ma co najmniej trzy chipy. Jeden przechowuje kod programu (PRG), drugi przechowuje grafikę (CHR) a ostatni to blokada. Układ scalony od grafiki może być pamięcią RAM, a nie ROM. Oznacza to, że kod programu/gry może kopiować z PRG ROM do CHR RAM. Nie mniej jednak sam PRG jest zawsze pamięcią tylko do odczytu - ROM. Jest też opcja umieszczania CHR wewnątrz ROMu PRG, więc fizycznie jedna kostka mniej.

Kilka słów o CPU

CPU to 8-bitowy, zmodyfikowany procesor 6502. Podobny do stosowanych w Apple 2, Atari  2600, C64 i wielu innych systemach. W czasie, gdy tworzono Famicoma procesor ten był za słaby na komputer, ale do konsoli nadawał się doskonale.

CPU ma 16-bitową szynę adresową, mającą dostęp do 64KB pamięci. 2^16 = 65536, czyli 64KB. Składa się na to pamięć 2KB RAMu CPU, porty do PPU/APU/kontrolerów, WRAMu (jeśli jest w na cartridge'u) oraz 32KB na PRG ROM. Szesnastobitowe adresy są zapisane w hexie (systemie szesnastkowym), więc składają się z czterech znaków, które poprzedza symbol $. Przykładowo: wewnętrzny RAM jest pomiędzy $0000 - $0800. $0800 = 2048 czyli 2KB. 32KB szybko stały się niewystarczające dla gier, dlatego zaczęto stosować mappery. Mappery mogą podmieniać banki pamięci kodu PRG albo grafiki CHR. Na przykład mapper MMC3 pozwala na 512KB dla PRG i 256KB dla CHR. Nie ma limitów teoretycznych jeśli chodzi o rozmiary pamięci w mapperach. Najczęściej występujące to 128KB dla PRG i 64KB dla CHR.


Kilka słów o PPU

PPU w NESie to chip odpowiedzialny za wyświetlanie grafiki. Obsługuje wewnętrzny RAM na sprite'y i paletę kolorów. Jeden RAM znajdujący się na płycie głównej konsoli utrzymuje tło, a wszystkie grafiki wyświetlane na bieżąco są brane z carta (pamięci CHR).

Twój program nie jest odtwarzany przez PPU. PPU zawsze wykonuje tę samą sekwencję wyświetlania. Możesz jedynie ustawić takie opcje jak kolory i przewijanie obrazu (scrolling). PPU przetwarza jedną linię obrazu na raz. Najpierw pobierane są sprite'y z pamięci CHR (tej na cartcie). Jeśli jest ich więcej niż 8 na jednej linii pozostałe są ignorowane. Przez to właśnie w niektórych grach jak np Super Dodge Ball obraz mruga, kiedy dużo dzieje się na ekranie. Po sprite'ach wyświetlane jest tło. Kiedy przelecą wszystkie linie obrazu nastaje moment, kiedy nie są wysyłana żadna grafika. Ta chwila nazywana jest VBlank'iem i jest to jedyny moment, kiedy mogą się dokonać jakieś zmiany w grafice. W systemie PAL czas powrotu działka elektronowego z powrotem na górę ekranu (czyli czas VBlank'a) trwa dłużej, niż w NTSC przez co istnieje więcej czasu na aktualizację grafiki. Niektóre gry i demka nie działają poprawnie w systemie NTSC poprzez różnice w czasie VBlank'a. Oba systemy NTSC i PAL mają rozdzielczość 256x240 pikseli, ale 8 górnych i 8 dolnych linii jest ucinane podczas wyświetlania NTSC przez co obraz ogranicza się do 256x224 pikseli. Telewizor może odciąć kolejne 0-8 linii, więc lepiej zachować drobny odstęp przed wyświetleniem ważnych rzeczy.

NTSC chodzi na 60Hz, PAL na 50Hz. Przez to gry pisane pod NTSC są spowolnione ruchowo i mają wolniej odtwarzane dźwięki.



Kilka słów o Grafice

Tiles'y
Cała grafika składa się z tilesów o wymiarach 8x8 pikseli. System tile'i oznacza mniejsze zapotrzebowanie na pamięć (która była droga w tamtych czasach) i zarazem czyni niemożliwymi takie rzeczy jak obrazki bitmapowe, czy grafika 3d - praktycznie nieosiągalne. By przejrzeć wszystkie tilesy z gry, pobierz Tile Molester i otwórz swój plik .nes. Przewiń w dół, aż graficzki zaczną wyglądać jak graficzki, nie śnieg. Tak, te małe tilesy są układane w grze tak, by tworzyły większe obrazki.

Sprite'y
PPU może pomieścić 64 sprite'y, czyli "duszki" czyli to co się porusza na ekranie jak np. Mario. Na jednej linii obrazu może być wyświetlane maksymalnie 8 sprite'ów, ew. kolejne są pomijane. Stąd bierze się mruganie obrazu, kiedy jest wyświetlanych za dużo sprite'ów na raz.

Tło
To widoczki przewijające się naraz w całości. Sprite'y mogą być wyświetlane przed tłem lub za nim. Ekran mieści 32x30 tilesów tła. Wewnętrznego RAMu starcza na utrzymanie dwóch takich ekranów. Podczas przewijania obrazu grafika jest aktualizowana poza obrazem, zanim zostanie wyświetlona na ekranie.

Tabele Szablonów (Pattern Tables)
Miejsca gdzie są przechowywane dane aktualnych tiles'ów. Znajduje się na ROMie lub RAMie na cartcie. Każda Tabela mieści 256 tilesów. Jedna jest odpowiedzialna za tła, druga za sprite'y. Wszystkie grafiki wyświetlane w danym momencie na ekranie muszą się w nich zawierać. Pattern Table zawiera połowę informacji potrzebną do wyświetlenia tile'a.

Tabele Atrybutów (Attribute Tables)
Te tabele zawierają informację o kolorach w kwadratach 2x2 tilesy. Oznacza to, że na obszarze 16x16pikseli mogą występować tylko cztery kolory wybrane z jednej palety. Nie da się użyć więcej, niż 4 kolory. Jeśli znajdziesz fragment na środku ekranu, gdzie np. tło ma więcej niż 4 kolorki w obszarze ramki 16x16 pixeli to znaczy, że patrzysz na złączenie kilku bloczków 16x16, albo występuje tam jakiś sprite, a nie tło.

Palety
Są dwie osobne palety kolorów: dla tła i dla spriteów. Każda z nich ma po 16 kolorów.

Wyświetlając tile na ekranie brany jest indeks koloru danego piksela z Pattern Table i Atribute Table.  Potem by określić już sam kolor sprawdzana jest Paleta kolorów.



O samej grafice jeszcze będzie, także nie przejmuj się jeśli nie rozumiesz wszystkiego od razu.

Literatura uzupełniająca:
Oryginał [ENG]:
http://www.nintendoage.com/forum/messageview.cfm?catid=22&threadid=4291

Dobry opis grafiki znajdziesz w wątku Siudyma [PL]:
http://www.forum.emunes.pl/index.php?topic=1590.0

Podręcznik ASM 6502 dla Atari [PL]:
http://atarionline.pl/biblioteka/materialy_ksiazkowe/Asembler%206502%20(v2).pdf

Trochę rozszerzony opis grafiki, rejestry PPU [ENG]:
http://web.textfiles.com/games/nesgfx.txt

Programowanie na NES'a w pigułce z NES DEV [eng]:
http://nesdev.com/NESprgmn.txt

Dorzut linków od siudyma:

http://badderhacksnet.ipage.com/badderhacks/index.php?option=com_content&view=article&id=270:the-nes-picture-processing-unit-ppu&catid=14:dr-floppy&Itemid=7

I dwa ciekawe linki, przejrzyscie opisane:

http://ludumdare.com/compo/2014/06/23/creating-my-first-nes-game/

http://www.tummaigames.com/blog/