kategoria: ANSI C
[#31] Re: Debugowanie ACE'a

@asman, post #30

No to zdejmę ze stosu rzeczy, po kolei:

6. zostało bo te printy mi się przydawały w debugowaniu. Jeszcze nie skończyłem z tym walczyć (vide VBR), jak skończę to to wywalę permanentnie. Póki co czeka na ewentualne użycie. ;)

5. każdy ma swoje ograniczenia poznawcze i niektórzy myślą pokrętnie - lepsze to niż nie myśleć i nie pisać nic. ;) A tak serio to może kiedyś wymyślę jak to napisać czyściej. Póki co pomysłu nie mam.

4. Dobre! Z drugiej strony jak to zrobić czyściej? Jak zatrzymasz najpierw DMA to któreś przerwanie Ci może chlasnąć powodując włączenie DMA na nowo.

3. O, ten OsFlush sprawdzę - znalazłem Twój wpis z EAB. Jeśli coś w kodzie się zmieniło to daj znać, jak nie to spróbuję to przepisać na C ale dziś nie dam rady. Jak spojrzałem na ten kod to nie mogę się nadziwić że można coś takiego wygodnie czytać. Pewnie Ty masz tak z moim. ;)

2. O, chyba to to dlatego tam jest.
2a. Coppera sobie inicjuję w copper.c w funkcji copperCreate(). Ona idzie później niż systemCreate() więc już nie masz żadnej aktywnej copperlisty - LoadView(0) wyłącza systemową.

1. Raczej zostaje gdzie jest - system.c tym zarządza, tworzy to logiczną całość jak dla mnie - "używając" systemu musisz przełączyć przerwania, przestając używać systemu przerwania przywracasz, co robią funkcje systemUse() i systemUnuse().

1a. Tu coś było, ale już wiem że jestem gapą i w reszcie tak zrobiłem a w tym nie. Dobre, zrobię. Wyszedłem z założenia że wystarczy sprawdzić icr na CIA, ale skoro mówisz że nie, to nie. ;) Już wiem czemu tak zrobiłem - bo założyłem że nic innego nie wywołuje int2. Co jeszcze go wywołuje? "some of disk functions", czyli co?

1b. I tu znowu - czy to dotyczy tylko int2? I co oznacza że za szybko? Nie zapisze to się w rejestrze za pierwszym razem czy ki czort?

Ostatnia aktualizacja: 06.11.2018 19:38:31 przez teh_KaiN
[#32] Re: Debugowanie ACE'a

@teh_KaiN, post #31

1b. To dotyczy każdego przerwania tu male wyjaśnienie od Stingraya (link).

1a. To chyba raczej kwestia pisania w zgodzie z wytycznymi.

3. To ten kod.

4. Ja robie to tak
kod:
		move.w	#$7fff,d0
		move.w	d0,dmacon(a5)	;dma off
		move.w	d0,intena(a5)	;disable ints
		move.w	d0,intreq(a5)	;clear pending ints


5. na przkyład taki kawałek kodu
if(ubKeyReleased) {
		keyIntSetState(pKeyManager, ubKeyCode, KEY_NACTIVE);
	}
	else {
		keyIntSetState(pKeyManager, ubKeyCode, KEY_ACTIVE);
	}


zapisałbym tak
UBYTE state = KEY_ACTIVE
if (ubKeyReleased)
{
    state = KEY_NACTIVE
}
keyIntSetState(pKeyManager, ubKeyCode, state);


To tyle na tą chwilę :)
[#33] Re: Debugowanie ACE'a

@asman, post #32

1a. no spoko, dla porządku zmieniłem. Masz pomysł co jeszcze wywołuje przerwanie int2 prócz CIA?

1b. dzięki, dodałem.

4. Poprawię, skoro u Ciebie działa to u mnie będzie też działać ;)

5. Czemu ja to tak zapisałem to nie wiem. Zmieniłem na:
keyIntSetState(
		pKeyManager, ubKeyCode, ubKeyReleased ? KEY_NACTIVE : KEY_ACTIVE
	);
[#34] Re: Debugowanie ACE'a

@teh_KaiN, post #33

1a. Nie mam pomysłu, bo jak dobrze widzę to tylko PORTS lata na poziomie 2. Nie mniej ja u siebie sprawdzam czy to faktycznie PORTS generuje przerwanie.

Nie mogę ogarnąć kodu bo co chwila widzę kompilację warunkową - nie widzę powodu by dawać co chwilę #if defined(AMIGA) , skupiłbym się tylko na wersji dla Ami.

Strasznie denerwujące są te wyowłania logera co chwilę i masa różnych warunków do tego. Nie wiem jak to tam się skompiluje do kodu produkcyjnego. Czy przypadkiem nie jest tak że loggery znikną a warunki zostaną, które zresztą mogą generować 'side effects' bez których funkcja przestanie działać ? Ogólnie mam wrażenie że to wszystko jest bardzo ciężkie. przeniósłbym te wywołania loggerów z warunkami do innego modułu by 1) wyczyścić kod 2) Dać bezbolesną możliwość usunięcia tego w kodzie produkcyjnym. Nie wiem co ty na to.

To tylę na tą chwilę.

PS. Zapomniałem podziękować Administracji za przeniesienie postów. Dzięki wielkie.

Ostatnia aktualizacja: 07.11.2018 14:49:37 przez asman
[#35] Re: Debugowanie ACE'a

@asman, post #34

defined(AMIGA) zostaje przynajmniej na razie bo pisząc OpenFire chcę mieć aplikację serwera dedykowanego również napisaną w ACE, żeby nie trzymać logiki gry w dwóch różnych projektach. Sam ACE ma korzystać z SDL na innych platformach, powodując że pisząc w pewnym podzbiorze jesteś w stanie automatycznie wydać wersję na PC i inne. To dotyczy też AMInera, którego planuję puścić na Steama jak skończymy. Jest pomysł by implementacje pod dane platformy rzucić na oddzielne pliki żeby tych ifdefów nie było ale jeszcze nie wiem jak to dobrze ugryźć. Póki co jest jak jest i obecnie można (albo można było bo dawno nie sprawdzałem) zbudować ACE'a w wersji headless (bez gfx, inputa i audio) na x86.

Daj przykład tej nieczytelności loggerów (choćby nazwa pliku lub funkcji), powiem Ci czy tak ma być czy faktycznie trzeba to zmienić. ;)

Ostatnia aktualizacja: 07.11.2018 16:07:33 przez teh_KaiN
[#36] Re: Czy opłaca się tworzyć gry?

@teh_KaiN, post #27

Przerwania - byłem tam i okazuje się że OS dalej się wpieprza swoimi rzeczami w te przerwania, zjadając czas CPU. Dowód - AddIntServer narzuca format argumentów callbacków przerwania, więc nie jest to bezpośrednia podmiana wektorów na sprzęcie, tylko wciąż masz wrapper który oddaje kontrolę OSowi do robienia newralgicznych rzeczy.

W grach mierzę sobie czas tak jak mi Asman kiedyś zasugerował, żeby zmieniać kolor zerowy przed i po wykonaniu jakiegoś fragmentu głównej pętli, co w rezultacie da kolorowy pasek w tle proporcjonalnie gruby do czasu wykonania. Przed zawłaszczeniem HW kolorowe paski zaczynały się i kończyły w losowych miejscach, po zawłaszczeniu HW paski co klatkę pojawiają się w tym samym momencie i są zawsze takiej samej grubości.

AddIntServer oczywiscie nie polega na podmianie wektorow - dodaje handler do listy, obslugiwanej przez systemowy handler przerwan. Systemowy handler jest maly i szybki wiec narzut nie jest duzy. Problemy, ktore opisujesz wynikaja z przelaczania taskow przez system ale mozna sie ich pozbyc w latwy sposob. Musisz zmienic priorytet swojego tasku na najwyzszy - wtedy system nie bedzie switchowal twojego tasku, ktory bedzie mial praktycznie caly czas procesora. Jest to cos w rodzaju wywolania Forbid ale z obsluga Wait. Czyli SetTaskPri(FindTask(NULL), 127) przed miejscem, gdzie potrzebujesz czaly czas procesora i SetTaskPri(FindTask(NULL), 0) tam, gdzie chcesz np. zaladowac z dysku itp. W ten sposob mozna uniknac problemow przy odtwarzaniu stanu systemu.
Oczywisice to ma sens, gdy wykorzystujesz system np. do ladowania. Jesli przejmujesz calosc i wszysko robisz przez hardware, to mozna pominac kwestie zachowania/odtworenia stanu systemu.
Btw: ta metoda timingu ma juz swoje lata - stosowalem ja na Amidze jeszcze przed 1990 :)))
[#37] Re: Czy opłaca się tworzyć gry?

@docent, post #36


Czyli SetTaskPri(FindTask(NULL), 127) przed miejscem, gdzie potrzebujesz czaly czas procesora i SetTaskPri(FindTask(NULL), 0) tam, gdzie chcesz np. zaladowac z dysku itp.


Nie musisz dawać SetTaskPri(self, 0) przed czytaniem z dysku. Twój program będzie czekał na sygnał po wywołaniu Read() i jego maksymalny priorytet nie będzie przeszkadzał. Dopiero kiedy filesystem skończy i odeśle pakiet twój proces dostanie sygnał i znowu będzie pracował z najwyższym priorytetem blokując wszystko inne.
[#38] Re: Czy opłaca się tworzyć gry?

@mschulz, post #37

Nie musisz dawać SetTaskPri(self, 0) przed czytaniem z dysku. Twój program będzie czekał na sygnał po wywołaniu Read() i jego maksymalny priorytet nie będzie przeszkadzał. Dopiero kiedy filesystem skończy i odeśle pakiet twój proces dostanie sygnał i znowu będzie pracował z najwyższym priorytetem blokując wszystko inne.

Generalnie masz racje - w normalnych warunkach dos bedzie czekal na odpowiedz z filesystemu i device, ale kazdy reschedule, ktory spowoduje ponowne aktywowanie glownego tasku zalatwi cale ladowanie.
Mozna to np. zrobic tak:
task=FindTask(NULL);
SetTaskPri(task, 127);
task->tc_ExceptCode=func;
SetExcept(0x1000,0x1000);
Wczesniej ustawic przerwanie tak, aby zostalo wywolane tuz po tym, jak dos wysle pakiet do filesystemu i na przerwaniu zrobic Signal(task, 0x1000);
Spowoduje to zreschedulowanie tasku z priorytetem 127 i wywolanie func (moze byc pusta). Nie wydaje mi sie, by w tej sytuacji os zreschedulowal proces filesystemu, ale nie testowalem tego wiec wszystko jest mozliwe :)
Druga opcja to uzyc sygnalu, uzywanego przez dos:
Signal(task, 0x100);
Open() powinien w tym momencie natychmiast wyjsc z Wait bez czekania na odpowiedz filesystemu i zwrocic jakis blad (albo i polozyc caly system :)
W sumie to mozna zastosowac pierwsza metode bez przerwan, wystarczy SetExcept(0x100, 0x100) i pewnie zdarzy sie podobnie - po pierwszym pakiecie glowny task zostanie zreschedulowany i filesystem wiecej juz nic nie zdziala...

Dlatego dla swietego spokoju na czas ladowania lepiej ustawic normalny priorytet.
[#39] Re: Czy opłaca się tworzyć gry?

@docent, post #38

ale kazdy reschedule, ktory spowoduje ponowne aktywowanie glownego tasku zalatwi cale ladowanie.
W jaki sposób może dojść do aktywowania tasku, który czeka na sygnał? Oprócz nadejścia tego sygnału oczywiście.
[#40] Re: Czy opłaca się tworzyć gry?

@Krashan, post #39

Task exception - powoduje aktywacje tasku i wywolanie tc_ExceptCode przy pojawieniu sie sygnalu, zdefiniowanego przez SetExcept, nawet jesli task nie czeka w danym momencie na ten signal. Technicznie rzecz biorac, mozna to potraktowac jak uruchomienie subtasku w kontekscie tasku ale w efekcie subtask bedzie zreschedulowanym taskiem z jego priorytetem.
W przypadku wysokiego priorytetu pozostale taski juz swojego czasu nie dostana.
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem