kategoria: ANSI C
[#1] Przerwanie blittera w VBCC
Cały dzień nad tym siedzę, próbuję na pierdyliard sposobów i nie wiem... Przykładów w necie oczywiście próżno szukać. Mam taki nagłówek handlera przerwania:
__amigainterrupt void blitManagerHandler(__reg("a0") struct Custom *cstm, __reg("a1") tBlitManager *pBlitManager)

I oczywiście nie działa. Próbowałem dodawać __saveds, __interrupt zamiast __amigainterrupt, zrobić z tego funkcję zwracającą ULONG = 0. Handler mimo to nie działa i pomimo miliona blitów nie robi ani razu byle pierdoły:
cstm->color[0] = 0x0F00;
	++pBlitManager->uwBlitPos;

Próbowałem też dobrać się do struktury custom przez zewnętrzną zmienną, też nie działa. Dokładny wygląd struktury pBlitManager raczej nie ma znaczenia, więc nie będę go tu przytaczał. Wygląda to tak, jakby SetIntVector kończyło się błędem. Handler rejestruję tak:

g_sBlitManager.pInt->is_Node.ln_Succ = 0;
	g_sBlitManager.pInt->is_Node.ln_Pred = 0;
	g_sBlitManager.pInt->is_Node.ln_Type = NT_INTERRUPT;
	g_sBlitManager.pInt->is_Node.ln_Pri = 10;
	g_sBlitManager.pInt->is_Node.ln_Name = g_sBlitManager.szHandlerName;
	g_sBlitManager.pInt->is_Data = &g_sBlitManager;
	g_sBlitManager.pInt->is_Code = blitManagerHandler;
	
	g_sBlitManager.pPrevInt = SetIntVector(INTB_BLIT, g_sBlitManager.pInt);

Oczywiście żadnych zwiech, crashy, czegokolwiek. Jedyny przykład, jaki znalazłem dla VBCC to to ustrojstwo, robię niby tak samo i nie działa. Pomysły?
[wyróżniony] [#2] Re: Przerwanie blittera w VBCC

@teh_KaiN, post #1

Przerwanie blittera (INTB_BLIT) ustawiasz w intena i intreq ?
Dma dla blittera masz także włączone (DMAF_BLITTER) ?
[#3] Re: Przerwanie blittera w VBCC

@asman, post #2

Jesteś wielki. Ale nadal jestem głupi :)

Mam takie linie:
g_sBlitManager.pPrevInt = SetIntVector(INTB_BLIT, g_sBlitManager.pInt);
	logWrite("Interrupt handler set to %p, fn: %p\n", g_sBlitManager.pInt, blitManagerHandler);
	
	custom.dmacon = DMAF_SETCLR | DMAF_BLITTER;
	logWrite("DMACON set\n");
	custom.intena = INTF_SETCLR | INTF_BLIT;
	logWrite("INTENA set\n");
	custom.intreq = INTF_SETCLR | INTF_BLIT;
	logWrite("INTREQ set\n");

Znowu na modłę tego jednego przykładu, co wisi w necie. I ostatnie, co ląduje w logu to "DMACON set", potem zwiecha wszystkiego, nawet mysz nie drgnie. Albo jest za późna godzina albo coś jeszcze napsułem. Może jednak nagłówek handlera nie taki?

Jak zamieniłem kolejnością intena z intreq to intreq się wykonuje, na intena nadal zwiecha.

Ostatnia aktualizacja: 02.04.2015 22:07:21 przez teh_KaiN
[#4] Re: Przerwanie blittera w VBCC

@teh_KaiN, post #3

Wysyłasz log na konsolę? Czy wiesz, że to wymaga użycia blittera, stąd (prawdopodobnie) zwiecha.

Ostatnia aktualizacja: 02.04.2015 22:10:19 przez Hexmage960
[#5] Re: Przerwanie blittera w VBCC

@Hexmage960, post #4

Nawet jeśli blitter jest używany do odmalowywania konsoli, to czy to powinno w efekcie wieszać cały system, gdy handler jest pustą funkcją? I nie, nie loguję do konsoli, tylko przez fwrite do pliku.

Ostatnia aktualizacja: 02.04.2015 22:15:37 przez teh_KaiN
[wyróżniony] [#6] Re: Przerwanie blittera w VBCC

@teh_KaiN, post #5

Właśnie zerknąłem do dokumentacji, Twój handler prawdopodobnie powinien wyczyścić flagę INTF_BLIT w intreq przed wyjściem z handlera (opieram się na przykładzie).

custom.intreq = INTF_BLIT;


Ostatnia aktualizacja: 02.04.2015 22:34:02 przez Hexmage960
[#7] Re: Przerwanie blittera w VBCC

@Hexmage960, post #6

Mamy zwycięzcę. :) Rzeczywiście, durny jestem, nawet w podanym przeze mnie przykładzie kodu było takie coś.

Teraz mi się tylko wysypuje przy wyjściu z gry, ale to grubo po zamknięciu menedżera, bo przy zamykaniu okna intuition (rozciągniątego na cały screen żeby intuitionem przechwytywać klawę i mysz, na to idzie view po którym gra rysuje), więc pewnie coś gdzie indziej. Chyba, że o czymś zapomniałem? W tym przykładzie w ogóle nie jest przywracany poprzedni handler, ale takie rozwiązanie nie wydaje mi się być zbyt czyste.

WaitBlit();
	custom.dmacon = DMAF_BLITTER;
	custom.intreq = INTF_BLIT;
	custom.intena = INTF_BLIT;
	SetIntVector(INTB_BLIT, g_sBlitManager.pPrevInt);


Ale to już jutro, dzisiaj na to za późno.
[wyróżniony] [#8] Re: Przerwanie blittera w VBCC

@teh_KaiN, post #7

By było czysto musisz zapamiętać stan dmacon i intena
//store hardware registers
	custom = ((struct Custom*)0xDFF000);
	oldIntena = custom->intenar;
	oldDma = custom->dmaconr;


a potem je przy wyjsciu przywrócić. Im wcześniej tym lepiej.
void EnableOS(void)
{
	//stop ints and dma
	stopIntsDma();

	//restore hardware registers
	custom->intena = oldIntena | 0xC000;
	custom->dmacon = oldDma | 0x8000;
        //dalsza część


i funkcja
static void stopIntsDma(void)
{
	UWORD t = 0x7fff;
	custom->intena = t;
	custom->dmacon = t;
	custom->intreq = t;
}

tego uworda t możesz zamienić w tych liniach, bo i tak kompilator (przynajmniej vbcc) i tak zrobi po wiejsku czyli
move.w #$7fff,intena(a5)
move.w #$7fff,dmacon(a5)
move.w #$7fff,intreq(a5)

zamiast zrobić jak należy
move.w #$7fff,d0
move.w d0,intena(a5)
move.w d0,dmacon(a5)
move.w d0,intreq(a5)


Acha i jeszcze jedno. przed zatrzymaniem przerwań i dma, można (należy???) poczekać na wygaszenie pionowe. Na przykład tak
void ScreenWaitForFrame(void)
{
	while(TRUE)
	{
		ULONG line = (*((ULONG*)0xDFF004)) & 0x1ff00;

		if (line == (303 << 8))
		{
			break;
		}
	}
}


Ostatnia aktualizacja: 02.04.2015 23:29:48 przez asman
[#9] Re: Przerwanie blittera w VBCC

@asman, post #8

Już śmiga :)
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