Marca 29, 2024, 08:25: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 ... 4 5 [6] 7 8 ... 11
  Drukuj  
Autor Wątek: Programowanie Nes'a (procesora 6502)  (Przeczytany 78611 razy)
0 użytkowników i 1 Gość przegląda ten wątek.
Grucus
Chorąży
***
Offline Offline

Wiadomości: 125


« Odpowiedz #100 : Czerwca 30, 2010, 19:18:05 »

Nie do końca dobry jest ten artykuł...

O instrukcjach stosowych znalazłem bardzo dobry artykuł, a jego esencją są dwa kawałki kodu, ktore do końca wyjaśniły o co idzie. Ideą tego kodu jest, że wszystkie natychmiastowe dane przechodzą przez akumulator i istnieją rozkazy umożliwiające operacje cząstkowe (np. zanim umieścimy na stosie zawartość rejestru X musimy umieścić ją w akumulatorze i dopiero, gdy znajduje się ona w akumulatorze wrzucamy ją na stos).

Prawda, nie można zapisać stałej bezpośrednio na stos (adresowanie natychmiastowe). Najpierw należy ją wpisać do akumulatora, dopiero jego zawartość można odłożyć na stosie, programista może odkładać na stosie tylko zawartość A lub P! [tu był bug - dobrze, że koledzy po fachu kontrolują, co za głupoty inni wypisują] Podobnie się ma rzecz ze wskaźnikiem stosu, nie można go zainicjować wartością wprost, pozycję szczytu stosu należy najpierw zapisać do rejestru X, a następnie przesłać do S. Rozwiązanie to może wydawać się dziwne i nie logiczne, w porównaniu choćby z 8-bitowymi intelami tamtego okresu, ale właśnie to dzięki temu znacząco udało się uprościć blok zarządzania procesora, a co za tym idzie nieco przyśpieszyć szybkość pracy w porównaniu z tymi intelami, niestety utrudnia programowanie w asm i pogarsza czytelność kodu.

;* 1 Kod *

 ldx #$ff   ; Ustaw wskaźnik stosu (rejestr S), na pierwszy element
 txs      ; s = x = #$ff (jest to jedna z czynności wykonywana w kodzie inicjalizacyjnym)

Te komentarze są tragiczne, zasada mówi, że komentarz opisuje, co robi linijka, w której się znajduje (trochę inaczej się to ma w przypadku bloków instrukcji). Pierwsza linijka wcale nie ustawia wskaźnika stosu, przecież tam nie ma operacji na S... obie oczywiście poprawnie inicjują stos w obszarze pamięci. Warto także wiedzieć że S ma tak na prawdę 9 bitów! tylko że najstarszy jest na stałe ustawiony na "1" bo stos w 6502 co prawda może mieć zaledwie 256 elementów. ale są one umieszczone na pierwszej stronie pamięci (0100h - 01FFh), ta zablokowana jedynka na najstarszej pozycja zapewnia natychmiastowe wystawienie na magistrale adresowa właściwego aderesu, bez tracenia czasu na kombinowanie jak go obliczyć, kolejne przyśpieszenie... Dodatkowo stos, jako ze 6502 jest poprawioną kopia motoroli, w przeciwieństwie do inteli, jest stosem ze wskaźnikiem dekrementowanym, czyli po odłożeniu wartości na stos, kolejny element nie jest odkładany w komórce wyżej, a w komórce niżej. Poprawnym jest więc zainicjowanie stosu adresem najwyższym, czyli 01FFh (pamietamy o stałej jedynce, zapisujemy do S tylko 0FFh), odkładanie kolejnych wartości będzie powodowało przesuwanie wskaźnika stosu w stronę komórki 0100h. Warto jeszcze wiedzieć, że blok zarządzania procesora najpierw odkłada wartość na stosie, a później dekrementuje S, nie odwrotnie, dlatego wskaźnik stosu wskazuje na komórkę stosu, do której ma trafić bieżąca wartość, a nie komórkę, do której trafiła poprzednia (to drugie rozwiązanie jest stosowane we współczesnych procesorach). Ciekawe jeszcze tylko jaką wartość przyjmuje S po resecie, jeśli 0FFh to po co go inicjować? jeśli 0h to to by było mega bugiem popełnionym przez inżynierów z motoroli, jeśli S nie jest zmieniany podczas resetu to rzeczywiście taka inicjalizacja ma sens.

_push_stack:
;Położenie na stosie wartości rejestru A:
 lda #$e0   ; zapisanie stałej do akumulatora
 pha      ; odłożenie stałej zapisanej w A na stos (i dekrementacja wskaźnika stosu)
 
Dlaczego wszystkie te komentarze zawierają zawartość rejestrów a powinny wyniki wykonania instrukcji?..
Rejestry powinno się przedstawiać graficznie, jest to bardziej czytelne!

ldy #$bb   ; y = #$bb
 tya          ; a = y = #$bb
 pha      ; s = $fe  i a= #$bb

 txa          ; a = x; Przed polożeniem wartości x na stosie trzeba ją zapisać do A
 pha      ; Połóż wartość $ff (Pochodzącą z kodu inicjalizującego) na stosie. s=$fd

Bzdura, wykonałeś 3 instrukcje odłożenia wartości na stosie i żadnej zdjęcia wartości ze stosu, S wskazuje na 0FFh - 3h = 0FCh, tam trafi następna dana odłożona na stos.

;* 2 Kod *
_pull_stack:
  pla      ; Zdjęcie wartości $FF oraz skopiowanie jej do rejestru X
  tax      ; S = $fd

Jest to prawdą, tylko przy założeniu że kod ten stanowi integralną całość z poprzednim, dokładniej następuje po nim.
A teraz dla większych jaj zawartość S jest dobrze podana mimo, że policzona na podstawie błędnego założenia wcześniej,
wykonujesz jedno zdjęcie wartości ze stosu, S = 0FCh + 1h = 0FDh

 pla      ; Zdejmij ze stosu kolejną wartość (#$bb) i wrzuć ją do rejestru Y.
  tay      ; S = $fe.

  pla      ; Zdejmij $e0 na stos, a później zapisz do A.
      ; S = $ff - Od tego miejsca zaczęliśmy używać obszaru stosu do zapisu danych.

Dochodzą do tego jeszcze instrukcje:

;* -1 Umieszczające na stosie zawartość rejestru statusu procesora (rejestru P)  
        Rozkaz php ( rejestr P -> Stos)

;* -2 Zdejmujące wartość ze stosu do rejestru statusu  procesora (rejestru P)
        Rozkaz plp  ( rejestr  P <- Stos)


To by było na tyle odnośnie stosu. Szkoda, że nie ma on, żadnych sprzętowych zabezpieczeń przed przepełnieniami.

I co niby miałby zrobić procesor w chwili przepełnienia? Co najwyżej zgłosić przerwaniem jakiś błąd krytyczny, ale 6502 to nie te czasy, układy przerwań jeszcze wtedy raczkowały, zapełnienie stosu możesz sprawdzać programowo przecież, wydaje mi się że pisząc w asm te 256 bajtów to i tak za dużo;p Obowiązek dbania o nieprzepełnienie stosu tak czy siak spoczywa na programiście.
Poza tym uwaga Koksa, to co poprawił też było okrutną bzdurą, jak pisałem najlepiej pokazują to rysunki i tabelki, trudno to opisać zielonemu w tym temacie;p Nie polecam książki Kruszyńskiego ("uP 6502 i jego rodzina"), to jest to tam zupełnie zamotane, rysunki ą dobre, ale opis tragiczny. Znacznie lepiej poradził sobie z tym Ruszczyc ("Asm 6502"), celowo podaję polską literaturę, zobacz jak się co nazywa po polsku, tłumaczysz dosyć specyficzny tekst techniczno-naukowy, zadbaj o jego poziom, nie mam na myśli utworzenia na zasadzie 'jaki jestem mądry', a raczej na zasadzie 'jakie to proste', z tym że nie powinieneś dopuszczać w tłumaczeniu do niejednoznaczności, czy pisać jakiś bzdur.
Mogłem coś przeoczyć... Poza tym wszystkim w Asemblerze pierwsza kolumna to dyrektywy asemblera i etykiety, druga to rozkazy, staraj się tak pisać, zdecydowanie poprawia czytelność i umożliwia asemblację!
« Ostatnia zmiana: Czerwca 30, 2010, 22:46:19 wysłane przez Grucus » Zapisane
Koks
Major
*****
Offline Offline

Wiadomości: 580



« Odpowiedz #101 : Czerwca 30, 2010, 20:58:10 »

Najpierw należy ją wpisać do jednego z rejestrów (akumulator albo rejestr stanu procesora),
Do rejestru stanu procesora nie można nic wpisywać. Jego zawartość umieszcza się na stosie w celu późniejszego przywrócenia.


wskaźnik stosu wskazuje na komórkę stosu, do której ma trafić bieżąca wartość, a nie komórkę, do której trafiła poprzednia (to drugie rozwiązanie jest stosowane we współczesnych procesorach).
W jakich procesorach? Sprawdziłem, że w moim Celeronie stos działa dokładnie tak jak w 6502, różni się tylko rozmiarem wskaźnika i możliwością zmiany segmentu.
« Ostatnia zmiana: Czerwca 30, 2010, 21:07:14 wysłane przez Koks » Zapisane

Częste mycie skraca życie.
"If you have a fast, shiny new Pentium II, you might try using 44 kHz for the ultimate in sound quality." - readme od Unreala
https://drive.google.com/folderview?id=0B2TXQD5v-ZIVfjVQdTl2TTZiWmJ2LWZJajJzS0V4cDZBay04WjVGQkdQdnBDQzRlYkdQVGc&usp=sharing
Grucus
Chorąży
***
Offline Offline

Wiadomości: 125


« Odpowiedz #102 : Czerwca 30, 2010, 22:37:58 »

Do rejestru stanu procesora nie można nic wpisywać. Jego zawartość umieszcza się na stosie w celu późniejszego przywrócenia.
Racja pomotałem, naleciałości z intela:/ Programista ma tylko częściowy dostęp do tego rejestru, przez instrukcje kasowania i ustawiania bitów, o ile dobrze pamiętam 3 można ustawić, 4 skasować. Więc jednak można wpisywać kilka bitów ;p Kurcze jakoś tak byłem pewien, że można załadować cały P jedną instrukcją, patrze teraz do książki Ruszczyca i racja tylko te kilka bitów można modyfikować programowo.
Właściwie na upartego można tak: #wartość -> A -> stos -> P, tylko nie ma to sensu wszystkie niezbędne flagi w P można ustawiać/zerować programowo, grzebanie w całym rejestrze na raz może być niebezpieczne jak pisałem.

Czepiałem się bugów, a sam popełniłem olbrzymiego. Jak to mawia moja znajoma:"ale się wygłupiłam..." Może mój kontakt z 6502 ograniczę do grania w gry pisane pod maszyny z tym prockiem.

W jakich procesorach? Sprawdziłem, że w moim Celeronie stos działa dokładnie tak jak w 6502, różni się tylko rozmiarem wskaźnika i możliwością zmiany segmentu.
Na pewno MSP430 działa jak opisałem, w x86 jest chyba jak piszesz, nigdy nie miałem potrzeby przyjrzeć się temu jakoś bliżej. Z tym że chyba jednak najpierw jest zmiana adresu we wskaźniku, a później odłożenie danej na stosie, teraz nie potrafię tego znaleźć, jak znajdę napiszę na pewno, chyba że ty masz gotowca gdzieś pod ręką;p Podaj sznurka proszę. Poza tym Twój celeron nie jest nowy, jest po prostu nowszą wersją 8086, właściwie to ta architektura ma chyba z 30 lat...
« Ostatnia zmiana: Lipca 01, 2010, 00:13:22 wysłane przez Grucus » Zapisane
CodAsm
Szeregowy
*
Offline Offline

Wiadomości: 49


« Odpowiedz #103 : Czerwca 30, 2010, 23:58:51 »

Co do odpowiedzi:

1. Porawiłem to i owo w moim poprzednim poście
2. Moje komentarze opisują, krótkie bloki funkcjonalne, czasem dzielę czynności na dwulinijkowe, bo np. instrukcje ldx i txs traktuję jako pewną całość (przyzwyczajenie z Intela, poza tym wspominałem o operacjach cząstkowych).
3. Czasem wskaźnik rozumie się dla uproszczenia jako daną na, którą wskazuje, robi się tak w jezykach C/C++, aby nie komplikować sprawy (wewnętrzne mechanizmy są zaszyte w kompilatorach). Mozna to rozumieć jako pewną nieścisłosć, bo w asemblerach nie ma jako takich operatorów na wskaźnikach (no intel ma operatory seg i offset, ale to inna bajka).
4. Co do stosu bardziej przemawia do mnie informacja, że stos to zbiór zmiennych z podkreśleniem, ze dostęp mamy tylko do ostatnio dodanego elementu, a nie zbiór adresów, które mogą dodatkowo wskazywać na inne adresy, czytałem gdzieś, że w bardziej zaawansowanych programach na 6502 można stosować 3 poziomowe tablice wskaźników, a ja dopiero miesiąc temu dowiedziałem się o istnieniu NESAsm-a, to nie moje tempo...
« Ostatnia zmiana: Lipca 01, 2010, 00:40:07 wysłane przez CodAsm » Zapisane
dr00id88
Gość
« Odpowiedz #104 : Lipca 01, 2010, 00:39:32 »

Sluchaj czy nas aby na debili nie uwazasz;> My naprawde wiemy k***a czym sa wskazniki, takze daruj sobie ten opis;)
Zapisane
Grucus
Chorąży
***
Offline Offline

Wiadomości: 125


« Odpowiedz #105 : Lipca 01, 2010, 00:51:44 »

Chciałem coś napisać, ale dynamika zmian postów, poprawek i kasowania ich chyba mi nie pozwoli ostatecznie;p
Z zabawą ze wskaźnikami i ich arytmetyką jest jak w c, nie jest to ani przyjemne, ani przejrzyste, ale daje bardzo duże możliwości.
Co do trybów adresowania no to podstawa kursu Asm. Nie wiem jak bardzo nie używałeś google; ale: http://atarionline.pl/biblioteka/materialy_ksiazkowe/Asembler%206502%20%28v1%29.pdf rozdział 5, str. 93 bodajże. Nie wiem czy tam nie ma jakiś błędów powstałych podczas cyfryzacji. bo chyba ta książka jest w 2 wersjach, surowa i z poprawkami.
Zapisane
CodAsm
Szeregowy
*
Offline Offline

Wiadomości: 49


« Odpowiedz #106 : Lipca 01, 2010, 08:48:29 »

Wolę 6502jsm.txt z parodiusa i NES Doc. Kilka trybów adresowania używa się nie wiedząc, że takowe się stosuje. Tryby adresowania dopiero w użyciu mówią mi coś a nie w ebookach, więc nie będę się upierał, że dobrze je znam. Grucus ja dopiero poznaję podstawowe sprawy, mam poprawioną wersję tego ebooka, do którego link podałeś. Co do postów,to co jest niepotrzebne i nie związane z tematem trza usuwać, z czasem to powinno być bardziej stosowane w internecie Tongue.
« Ostatnia zmiana: Lipca 01, 2010, 09:08:51 wysłane przez CodAsm » Zapisane
Koks
Major
*****
Offline Offline

Wiadomości: 580



« Odpowiedz #107 : Lipca 01, 2010, 20:20:30 »

Zacząłem sobie coś pisać, fajna zabawa. Na razie nie udało mi się wydobyć dźwięku.
http://www.4shared.com/file/AEOWvLGq/PR2.html
Zapisane

Częste mycie skraca życie.
"If you have a fast, shiny new Pentium II, you might try using 44 kHz for the ultimate in sound quality." - readme od Unreala
https://drive.google.com/folderview?id=0B2TXQD5v-ZIVfjVQdTl2TTZiWmJ2LWZJajJzS0V4cDZBay04WjVGQkdQdnBDQzRlYkdQVGc&usp=sharing
CodAsm
Szeregowy
*
Offline Offline

Wiadomości: 49


« Odpowiedz #108 : Lipca 02, 2010, 12:18:11 »

Na początek warto zapoznać się z poniższym prostym kodem, odpowiada on za ciągły dzwięk w jednym kanale APU, nieraz zdarzało się slyszeć taki dźwięk jak konsola się zawiesiła. Dalej jest zresztą petla forever:

reset:
  lda #$01   ; square 1
  sta $4015
  lda #$08   ; period low
  sta $4002
  lda #$02   ; period high
  sta $4003
  lda #$bf   ; volume
  sta $4000
forever:
  jmp forever


port    -> $4015 port konfiguracyjny kanałów DMC + flagi licznika długości fali
         ->ang. $4015  ---d.nt21     DMC control and length counter enabled flags (write)

porty ->$4002/$4003- młodszy i starszy bajt licznika długości okresu fali.

port  -> $4001     EPPP NSSS     Sweep unit: enabled, period, negative, shift count


Więcej szczegółów:

http://wiki.nesdev.com/w/index.php/APU_Length_Counter  - licznik długości fali (po jakim czasie fala zostanie wyciszona)
http://wiki.nesdev.com/w/index.php/APU_Pulse - kanały odpowiedzialne za falę kwadratową
http://wiki.nesdev.com/w/index.php/APU_Envelope - jak zmienić głośność?              
http://wiki.nesdev.com/w/index.php/2A03 - ogólna mapa rejestrów 2A03 (pAPU)

no i na koniec dwa linki ogólnie omawiające rejesty APU:

http://wiki.nesdev.com/w/index.php/APU_registers
http://wiki.nesdev.com/w/index.php/APU          

Przepraszam za nieco chaotyczny post, ponieważ pisałem go w pośpiechu.
« Ostatnia zmiana: Lipca 02, 2010, 20:45:09 wysłane przez CodAsm » Zapisane
Koks
Major
*****
Offline Offline

Wiadomości: 580



« Odpowiedz #109 : Lipca 02, 2010, 15:29:51 »

Dzięki. Nie mogłem znaleźć, w jakich jednostkach podaje się okres fali. Okazało się że w jakichś dziwnych, ale na nesdev wiki podane są gotowe wzory:

tval = fCPU/(16*f)-1        prostokąt

tval = fCPU/(32*f)-1        trójkąt

gdzie:
tval - 11-bitowa wartość jaką trzeba wpisać,
f - częstotliwość fali [Hz],
fCPU - częstotliwość zegara procesora (około 1789000 NTSC i 1663000 PAL).
Zapisane

Częste mycie skraca życie.
"If you have a fast, shiny new Pentium II, you might try using 44 kHz for the ultimate in sound quality." - readme od Unreala
https://drive.google.com/folderview?id=0B2TXQD5v-ZIVfjVQdTl2TTZiWmJ2LWZJajJzS0V4cDZBay04WjVGQkdQdnBDQzRlYkdQVGc&usp=sharing
Grucus
Chorąży
***
Offline Offline

Wiadomości: 125


« Odpowiedz #110 : Lipca 02, 2010, 23:32:09 »

Okres, jako że jest czasem, zazwyczaj wyraża się w sekundach...

Co do trybów adresowania: Nie wyobrażam sobie wydajnego programowani (chyba nawet żadnego programowania) w asm bez znajomości tego, to podstawa.
Ja się uczyłem tak:
1. Architektura tego co programujemy - rejestry i do czego służą
2. Tryby adresowania
3. Lista instrukcji
4. Połączenie p-ktu 2.i 3. - jakie rozkazy i jakie tryby, przez jakie tryby można uzyskać dostęp do określonych rejestrów
5. Testy, próby, zabawy, generalnie kilogramy romantycznych godzin z klawiaturą Wink
Zapisane
CodAsm
Szeregowy
*
Offline Offline

Wiadomości: 49


« Odpowiedz #111 : Lipca 04, 2010, 18:23:15 »

Oto ogólny artykuł o układzie APU z NESDev. Niestety mnogość nazw układów moze sprawić, że tekst może być ciężkostrawny. Dodałem nieco przypisów, aby rozjaśnić to co może wydać się niezrozumiałe. Proszę o wyrozumialość jeżeli coś sknociłem. Gdyby przekład artykułu być kompletnym gniotem, usunę go.


APU

Jednostka APU (Audio Processing Unit) jest układem konsoli NES generującym dźwięk w grach. Istnieją dwa typy chipów realizujących funkcjonalność układu APU:
-RP2A03 (NTSC)
-RP2A07 (PAL)
Rejestry tego układu są odwzorowane w obszarze adresowym $4000-$4017.

Dla jasności, dokumentacja ta opisuje w skrócie operacje wykonywane przez APU, jednak nie odnosi się ona do, żadnej konkretnej realizacji sprzętowej. Jeśli tylko dane zachowanie jest udokumentowane, dokładny rodzaj licznika lub rejestru przesuwnego użytego do jego realizacji nie ma znaczena, Zresztą,bez dostępu do bardzo kosztownych narzędzi analizy (inżynierii) wstecznej na poziomie chipów, można jedynie spekulować nad dokładnym sposobem realizacji sprzętowej urządzenia.

Rejestry            Kanały dostępowe    Jednostki funkcjonalne
$4000-$4003    Fala Kwadratowa 1    Zegar, Licznik Długości Fali, Obwiednia dźwięku, Odchylenie
$4004-$4007    Fala Kwadratowa 2    Zegar, Licznik Długości Fali, Obwiednia dźwięku, Odchylenie
$4008-$400B    Fala Trójkątna       Zegar, Licznik Długości Fali, Licznik Liniowy
$400C-$400F    Szum               Zegar, Licznik Długości Fali, Obwiednia dźwięku,
                                                        Rejestr Przesuwny -> Zapis/Sprzężenie Zwrotne  
$4010-$4013    Kanał modulacji            Zegar,Czytnik Pamięci,Bufor Próbek,Układ Wyprowadzający
              przyrostowej (DMC)
$4015       Wszystkie               Aktywacja Licznika Długości Fali/Odczyt tejże
$4017       Wszystkie               Licznik Ramek/Sekwenser

---------------------------------------------------------------------------------------------------------
*Tu kilka wyjaśnień dotyczących tabelki. (CodAsm)

Dostęp do każdego kanału APU uzyskuje się za posrednictwem odpowiednich rejestrów zmapowanych w niewielkiej  przestrzeni pamięci ($4000-$4017). Każdy kanał ma kilka jednostek funkcjonalnych, zaś każda jednostka funkcjonalna posiada rejestr umozliwiający komunikację CPU z taką jednostką.
Starałem się, dobrać jak najstosowniejsze odpowiedniki jednostek funkcjonalnych, mogłem się mylić,  więc dla pewnego wyklarowania dalej podaję jak nazwy tych jednostek brzmią w oryginale oraz po zdaniu opisującym czym jest większość z tych jednostek.

-Zegar (Timer)- Jest on uzywany przez każdy z 5 kanałów i słuzy on do sterowania częstotliwością   dźwięku. Zawiera on dzielnik taktowany zegarem procesora (cykl dzielnika=cykl procesora)
-Licznik Długości Fali (Length Counter)- Jak nazwa wskazuje jest on odpowiedzialny za długość fali.
Jak to bywa z licznikami jest on ładowany pewną wartością początkową, która jest  sekwencyjnie dekrementowana aż do osiągnięcia zera. Po osiągnięciu zera kanał, którym steruje ten licznik jest całkowicie wyciszany
-Obwiednia dźwięku (Envelope)- generuje głośność o stałym natężeniu lub zmiennym (wtedy jest ładowana wartością, która jest sekwencyjnie dekrementowana. Sama obwiednia dźwięku jest, krótkim zapisem amplitudy dźwięku. Ma ona na celu upodobnienie danego dźwięku do jego odpowiednika w rzeczywistości.
-Odchylenie (Sweep)- Jednostka odchylenia słuzy do korekcji okresu fali kwadratowej (w górę lub w dół). Odchylanie fali w celu jej korekcji odbywa się co pewien czas (np. zgodnie z Licznikiem Ramek)
-Licznik liniowy (linear counter)
-Rejestr Przesuwny Zapis/Sprzężenie Zwrotne (shift register w/ feedback)
-Czytnik pamięci (memory reader)
-Bufor Próbek (Sample Buffer)
-Jednostka Wyprowadzająca (output unit)
-Dostępność i Stan Licznika Długości Fali (Length Counter enable and status )
Pozwala włączać/wyłączać poszczególne kanały oraz umożliwia odczyt aktualnego stanu kanałów oraz flag przerwań APU
-Licznik Ramek/Sekwenser (Frame Counter/Sequencer)- Taktuje on zegar z niską częstotliwością dla
poszczególnych kanałów oraz umozliwia opcjonalne generowanie przerwania z częstotliwością 60 Hz. Nazwa "Frame Counter" jest bardzo myląca, ponieważ nie ma on nic wspólnego z sygnałem Video.

---------------------------------------------------------------------------------------------------------

Każdy z kanałów posiada własną charakterystykę taktowania generatora próbek, mają one także układy modulujące w różny sposób sygnał. Układy modulatorów sterowane są zegarami Licznika Klatek/Sekwensera (Frame Counter/Sequencer).DMC odgrywa próbki podczas, gdy pozostałe kanały generują fale o róznych kształtach. Każda podjednostka należąca do określonego kanału działa równolegle i niezależnie od pozostałych jednostek układu, zaś modyfikacja jakiegoś parametru kanału dotyczy zazwyczaj tylko podjednostek kanałów. Taka zmiana jest wprowadzana dopiero w chwili rozpoczęcia kolejnego cyklu wewnętrznego układu.

Odczyt/Zapis rejestru stanu umożliwia udostępnianie i blokowanie kanałów, a także na sprawdzenie aktualnej wartości Rejestru Stanu Licznika.

Dane wyjściowe wszystkich kanałów są łączone z uzyciem nielinionego schematu miksowania

*APU posiada własny Mixer zbierający wszystkie wyniki z poszczególnych kanałów i przetwarzający je na analogowy sygnał Audio (CodAsm).
« Ostatnia zmiana: Lipca 04, 2010, 18:32:50 wysłane przez CodAsm » Zapisane
Merki
Gość
« Odpowiedz #112 : Lipca 05, 2010, 16:01:49 »

Witajcie znowu Wink pisalem do was kiedys na forum, nawet post gdzies sie zachowal tyle ze zapomnialem hasla i zalozylem nowe konto (e-mail ze zmiana hasla starego konta wciaz nie doszedl...). Koniec offtopu.

Mam nadzieje ze zrozumiecie ze jestem dopiero poczatkujacy i pewne terminy troche mi sie mieszaja Wink zacząłem studiowac nesasm.pdf z nespowerpack oraz dokumentacje nesa z nesdev. Jako pierwszy program z Nesasm.pdf to wyświetlenie jednolitego tła o kolorze niebieskim. O ile kilku instrukcji w bloku inicjajycjnym jeszcze nie rozumiem (co narazie do szczescia mi nie potrzebne), o tyle chciałbym zrozumieć o co chodzi z tym NMI i vblank bo już zupełnie namieszali.

O ile dobrze rozumiem NMI to rodzaj przerwania generowanego przez PPU. Jednak, żebu go uaktywnić potrzeba włączyć odpowiedni bit w rejestrze $2000 tak?

Wkleje więc może fragment kodu z programu :

Kod:
STX $2000    ; disable NMI
  STX $2001    ; disable rendering
  STX $4010    ; disable DMC IRQs

vblankwait1:       ; First wait for vblank to make sure PPU is ready
  BIT $2002
  BPL vblankwait1

Pierwsza instrukcja wpisuje 8 zer do rejestru 2000. Są tam rózne opcje, wśród nich jak czytam bit 7 mówi coś o NMI i vblank (ciężko mi zrozumieć-indicates whether a NMI should upon VBlank Czy chodzi o to, że przy vblank ma byc generowany NMI (1) czy też nie (0)?)

Druga instrukcja też wpisuje zera do 2001-brak obrazu. Teraz zaczyna się to czego nie rozumiem. Program niby czeka na vblank (czyli moment gdy działo elektronowe rysuje nową linie u gory ekranu). Instrukcja BIT nie wiem co robi ;/ I teraz koncowe pytania:

VBlank jest sygnałem który pojawia się zawsze niezależnie od konfiguracji rejestrów PPU?
NMI jest z kolei przerwaniem które może być generowane lub też nie podczas nadejścia sygnału vblank?

Pewnie lamerskie pytania zadałem, ale nie chcę wchodzić głębiej nie znając podstaw Wink



Zapisane
CodAsm
Szeregowy
*
Offline Offline

Wiadomości: 49


« Odpowiedz #113 : Lipca 05, 2010, 17:06:38 »

1. Tak więc po raz kolejny daję link do mojego przekładu kursu nesasm.pdf ze strony
    nespowerpak.com (Przekład jest w formacie pdf):

   http://www.plikos.pl/17pj/NesAsmPL.pdf.html  

    Merki, myślę, że powinno to nieco rozwiać twoje wątpliwości.

2. Jestem w trakcie poprawek przygotowanych przeze mnie polskich wersji artykułów z NESDev:
    *Rejestry PPU.
    *Kod inicjujący
    *Kilka innych, które mam w surowych wersjach, jest ich sporo, ale ich jakość merytoryczna
     wymaga jeszcze wiele godzin na poprawki i doszlifowanie
    *Zastanawiam się nad roszerzeniem oraz przeredagowaniem artykułu o APU, który umieściłem kilka
      postów wcześniej (Narazie sama teoria oderwana od rzeczywistości, więc niewielka użyteczność
      poza tym ciągle tabelki rozjeżdżają mi się w postach)

3. Ostatnio, bardziej zajmowałem się czytaniem kodów źródłowych, natomiast artykuły musiały zaczekać, w ciągu następnych dni postaram się nadrobić zaległości.



Oto artykuł o kodzie inicjującym:



Kod inicjalizacyjny

W momencie podłączenia konsoli NES do zasilania lub jej zresetowania, program powinien wykonać nastepujące czynności w ustalonym do tego celu banku.


*(Algorytm+ Kilka szczegółów implementacyjnych sprzętu)

-Ustaw Bit blokady IRQ (flaga ta nie dotyczy jednak wszystkich IRQ- w tym procedury RESET- gdyż  
 możliwa jest symulacja w kodzie programu Resetu za pomocą rokazu:
 jmp $FFFC)
 [jest tp skok jak do zwykłej procedury, wrzucającej na stos i zbierącej ze stosu adres powrotny]
-Blokada przerwania NMI dla PPU oraz blokda Rendering'u grafiki [Rendering to po prostu pozazywanie
 Tiles'ów Tła lub Sprite'ów na ekranie- przyp CodAsm]
-Inicjalizacja Wskaźnika Stosu (sp) wartością #$FF (młodszy bajt adresu pierwszego elementu na
 stosie)
-Inicjalizacja Mapper'a (jeśli takowy jest uzywany)

Od tego miejsca kod inicjujący może zostać umieszczony albo w ustalonym do tego (niezmiennym) banku albo w odrębnym banku. W tym celu należy przełączyć bank za pomocą instrukcji jmp.

-Zablokowanie/Trybu dziesiętnego (decymalnego). Jest to konieczne nie tylko dlatego, że układ 2A03 nie posiada trybu dziesiętnego, ale również w celu zagwarantowania zgodności ze standardowymi debugger'ami
-Blokada przerwań zegarowych APU (w przypadku, gdy uzywany jest Mapper wyzwalający przerwania IRQ)
-Zablokowanie przerwań kanału DMC (IRQ DMC- przerwanie generowane przez APU)
-Ustawienie całego uzywanego przez Twój program RAMU na określone wartości ( aby nie zawierały przypadkowych śmieci). Czesto dotyczy to obszaru RAM wewnętrznego (@ $0000-$07FF) i jeżeli jest to konieczne to również PRG-RAM (@ $6000-$7FFF). Natomiast nie dotyczy to obszarów, w których zapisane jest coś co chcemy pamiętać po (miękkim) Resecie konsoli (Np. Spis najlepszych wyników graczy- Highscores)

-Odczekanie co najmniej 30000 cykli przed odczytem lub zapisem rejestrów $2003-$2007 (Związane jest to ze stanem PPU po włączeniu zasilania). Najpowszechniej stosowanym rozwiązaniem jest oczekiwanie na moment, w którym PPU wygeneruje w rejestrze $2002 (PPUSTATUS -> tylko do odczytu) sygnał powrotu pionowego (W całym kodzie inicjalizacyjnym musi to być wykonane dwukrotnie)


Niektóre Mapper'y nie posiadają ustalonych banków, a zamiast tego w danej chwili przełączają 32KB pamięci- dotyczy to AxROM, BxROM, GxROM oraz niektórych konfiguracji MMC1.
Konieczne jest zapisanie Wektorów Przerwań, aż do miejsca, w którym wykonywany jest skok (jmp) do osobnej sekcji, jest to duplikowane w każdym banku. [Co do podkreślonego fragmentu zdania mam pewne wątpliwości -> CodAsm]
Często zdarza się, że obszar ostatniej 256 bajtowej strony pamięci zawiera Wektory Przerwań, początek kodu inicjalizującego oraz tramoplinę służącą do skoków pomiędzy kodami (danymi) dwóch różnych banków.

A teraz próbka kodu inicjalizującego, z odrobiną komentarzy:

Kod:

reset:
 sei ; Ignoruj IRQ
 cld ; Wyłącz Tryb Dziesiętny
 ldx  #$40
          stx  $4017 ; Wyłącz przerwania Ramek APU
          ldx  #$ff
          txs  
          stx  $2000
          stx  $2001
 stx  $4010
 
 ; Opcjonalnie (pominięte)
 ; Ustaw Mapper i Skocz do dalszej częsci kodu inicjalizującego

 ; Wyczyść flagę powrotu pionowego (VBlankFlag)
 ; Tak więc wiadomo już, że oczekujemy na rozpoczęcie się powrotu pionowego

 ; Pierwszy z dwóch okresów oczekiwania na powrót pionowy, aby mieć pewność, że stan  
          ; PPU jest ustabilizowany

@vblankwait1:
 bit  $2002
 bpl  @vblankwait1

 ; Teraz mamy około 30000 jałowych cykli zanim stan PPU zostanie ustabilizowany,
 ; Jedyną rzeczą, jaką można w tym czasie zrobić to zapisanie RAMU określonymi wartościami
 ; Tak więc wypełniamy pamięć wartościami $00, co odpowiada przygotowywaniu
          ;przez kompilatory jezyka C sekcji BSS.
 ; Dla wygody wartość x przy pierwszej iteracji wynosi zero
 
 txa
@clrmem:
 sta  $0000, x
 sta  $0100, x
 sta  $0300, x
 sta  $0400, x
 sta  $0500, x
 sta  $0600, x
 sta  $0700, x
 
 ; Adresy $0200-$02ff celowo pomijamy, gdyż druga strona pamięci RAM używana jest na
 ; potrzeby listy wyświetlanych Sprite'ów, kopiowanych do OAM
 ; OAM powinna zostać zainicjalizowana wartościami z Zakresu $EF-$FF, a nie zerami,
 ; gdyż w takim wypadku otrzymasz masę niepotrzebnych Sprite'ów- śmieci w punkcie (0,0)
 
 inx
 bne  @clrmem

 ;innymi rzeczami, które można wykonać pomiędzy powrotami pionowymi mogą być np.:
 ;-ustawienie Audio (Dźwięku)
 ;-wypełnienie rejestrów Mapper'a odpowiednimi wartościami.

@vblankwait2:
 bit $2002  
 bpl @vblankwait2
 
   
W miejscu znajdującym się za tym kodem można wypelnić danymi obszary nastepujących tablic:
-Name Tables (w tym Attribute Tables)
-Pattern Tables (o ile na panel głównym używana jest CHR-RAM)
-Palletes

Po wykonaniu wszystkich powyższych czynnosci można przystąpić do wyswietlania grafiki. [Operacje na wymienionych Tablicach, ale to już inna historia ->CodAsm]


      Oryginalna wersja artykułu pojawiła sie pod adresem:
         http://wiki.nesdev.com/w/index.php/Init_code
   

            

« Ostatnia zmiana: Lipca 23, 2010, 14:59:16 wysłane przez CodAsm » Zapisane
CodAsm
Szeregowy
*
Offline Offline

Wiadomości: 49


« Odpowiedz #114 : Lipca 23, 2010, 15:10:02 »

1. Dochodzę do wniosku, że nie ma sensu brać się za nic dopóki nie poznam porządnie architektury 6502 i nie napiszę   
   kilku rozsądnych programów, bo moja wiedza w tym zakresie kuleje. Odpuszczę sobie publikowanie moich   
   wypocin jeżeli chodzi o tegoroczne lato. Podrukowałem sobie tony dokumentacji i mam całe wakacje. Kiedy przyjdzie 
   czas wrócę do tłumaczeń.

2. Wracając do sposobu nauki byłem zawsze za tym, żeby czytać dużo kodu i jeżeli ewentualnie pojawi się jakieś
    dziwne adresowanie wtedy zajrzeć do odpowiedniego źródła, dotychczas to działało.
 
3. Grucus dzięki za cenne informacje o stosie 6502. Być może  moje komentarze do kodu są rzeczywiście nieczytelne.

Pozdr.                                                             
Zapisane
Koks
Major
*****
Offline Offline

Wiadomości: 580



« Odpowiedz #115 : Lipca 27, 2010, 21:24:59 »

NESASM jest zły  chess
http://www.nesdev.com/bbs/viewtopic.php?t=3726
Zapisane

Częste mycie skraca życie.
"If you have a fast, shiny new Pentium II, you might try using 44 kHz for the ultimate in sound quality." - readme od Unreala
https://drive.google.com/folderview?id=0B2TXQD5v-ZIVfjVQdTl2TTZiWmJ2LWZJajJzS0V4cDZBay04WjVGQkdQdnBDQzRlYkdQVGc&usp=sharing
CodAsm
Szeregowy
*
Offline Offline

Wiadomości: 49


« Odpowiedz #116 : Sierpnia 09, 2010, 22:17:17 »

Fajny opis NES.

http://nocash.emubase.de/everynes.htm
Zapisane
CodAsm
Szeregowy
*
Offline Offline

Wiadomości: 49


« Odpowiedz #117 : Września 06, 2010, 09:39:30 »

Mam pytanie dotyczące palety, bo nie jestem pewnien czy dobrze zrozumiałem jak to działa:

*Mamy po 16 wpisów palety dla Sprite'ów i dla Tła, każdy taki wpis zawiera numer koloru w systemie NES (mamy miejsce na 64, ale NES potrafi wyświetlić jedynie 52 z nich).

[Nie jestem pewien czy dobrze zrozumiałem działanie palety od tego miejsca]

Kolor dla danego piksela (powiedzmy, że chodzi nam o ten w górnym lewym rogu tilesa 8x8) jest liczony w następujący sposób:

a.) Pobierany jest najstarszy bit z pierwszej płaszczyzny Tile'a w Pattern Table
b.) Pobierany jest najstarszy bit z drugiej płaszczyzny Tile'a w Pattern Table
c.) Pobierane są odpowiednie 2 bity z odpowiedniego wpisu Attribute Table (powiedzmy, że policzyliśmy Square (16x16 pix), w którym znajduje się dany tile i wyizolowaliśmy odpowiednie 2 bity z wpisu w Attribute Table)

Teraz klecone są do kupy bity, które pobraliśmy w powyższych trzech krokach w następujący sposób:

                              ccba
                              ||||                        
                              |||+ Bit z pierwszego płatu Tilesa \ Te dwa bity wybierają kolor
                              ||+- Bit z drugiego płatu Tilesa     / z odpowiedniej 4 kolorowej                
                              ||                                               palety
                              |+-- \ Te dwa bity są pobrane z odpowiedniego wpisu w Attribute Table
                              +--- / (określają jednocześnie, która 4 kolorowa paleta została wybrana)

Więc powstaje nam teraz 4 bitowy offset, który dodajemy do odpowiedniej palety w zależności czy mamy do czynienia ze Sprite'm czy Tilesem Tła, czyli

 $3F00 + ccba = Adres Koloru
   lub
 $3F10 + ccba = Adres Koloru

I otrzymujemy odpowiedni adres wpisu palety, w którym jest zapisany kolor wyświetlanego w danej chwili piksela.

[Tu koniec tego czego nie jestem pewny]

Mam nadzieję, że za bardzo nie zagmatwałem.
Zapisane
Koks
Major
*****
Offline Offline

Wiadomości: 580



« Odpowiedz #118 : Września 06, 2010, 11:09:21 »

Attribute Table jest tylko dla tła, każdy sprite ma swój bajt z atrybutami w którym jest też numer palety.
Zapisane

Częste mycie skraca życie.
"If you have a fast, shiny new Pentium II, you might try using 44 kHz for the ultimate in sound quality." - readme od Unreala
https://drive.google.com/folderview?id=0B2TXQD5v-ZIVfjVQdTl2TTZiWmJ2LWZJajJzS0V4cDZBay04WjVGQkdQdnBDQzRlYkdQVGc&usp=sharing
CodAsm
Szeregowy
*
Offline Offline

Wiadomości: 49


« Odpowiedz #119 : Września 11, 2010, 07:22:05 »

1. Koks chciałem podziękować za szybką odpowiedź

2. Znalazłem ostatnio link do dość obszernego tutoriala NES napisanego przez bunnyboy'a (dużo o programowaniu APU):

   http://www.nintendoage.com/forum/messageview.cfm?catid=22&threadid=7155

   I kilka innych dokumentów i stron:

   http://neshla.sourceforge.net/
   http://graphics.stanford.edu/~ianbuck/proj/Nintendo/
   http://kevtris.org/nes/index.html
   http://jonathan.microclub.ch/NES_raster/index.html
   http://everything2.com/node/2023188
  
  
« Ostatnia zmiana: Września 11, 2010, 08:17:58 wysłane przez CodAsm » Zapisane
Strony: 1 ... 4 5 [6] 7 8 ... 11
  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.054 sekund z 19 zapytaniami.