| Start | Super Packer | Atari Graphics Studio / AGS | Graph2Font / G2F | Mads |   http://madteam.atari8.info  
SKŁAD GRUPY
PRODUKCJE
scena
gry
użytki
vbxe
SPRZĘT
Sio2SD/Pajero
Sio2SD/Rocky
Stereo/Pajero
GTIA/Psychol
ARTYKUŁY
DEMO EFFECTS
LINKI
   

Tebe/Madteam
IRQ zamiast DLI

IRQ zamiast DLI na atariarea

Z przerwaniem programu DLISTy (DLI) pewnie każdy się spotkał, pozwala zmieniać rejestry w kolejnych liniach obrazu, dodatkowo zawsze wcześniej należy użyć WSYNC ($D40A) aby zmiana zaszła od początku linii, czyli jeśli mamy obrazek o wysokości 200 linii, to 200x WSYNC oznacza że na wysokości 200 linii zmieniamy tylko rejestry i nic poza tym, nie mamy czasu CPU na nic innego. Zaletą IRQ jest możliwość określenia co ile linii ma zostać wywołane przerwanie (co 1 linię, dwie, trzy, osiem itd.), wadą ograniczenie możliwości dźwiękowych POKEY-a, muzyka musi zostać napisana uwzględniając korzystanie z TIMER-a. Jeśli ktoś chciałby popełnić jakiś efekt w większej liczbie kolorów IRQ pozwoli odzyskać część straconych cykli CPU.

Jak dużo?

Przeszło 2000 cykli dla obrazka o wysokości 200 linii. Poniżej przykład wyświetlenia obrazka Vidola 'Monster', tryb XLPaint Max (albo MCP - McPainter). Z eksperymentów wyszło że najbardziej opłaca się wywoływać IRQ co 2 linie (AUDF=1), dla wywołań co 1 linię wychodzi czasowo podobnie jak poprzez DLI, chyba że dokona się optymalizacji przerwań IRQ i wtedy zaczyna się odzyskiwać cykle CPU jednak najbardziej efektywne jest wywołanie co 2 linie. IRQ nie takie straszne, chcecie zawalczyć o wolne cykle CPU, pomyślcie o IRQ jako alternatywie.

Zarys działania programu. Program startuje IRQ z poziomu przerwania DLI, czas trwania przerwania kontroluje zmienna LINE, zmniejszana z każdym wywołaniem IRQ.

	icl 'atari.hea'

height	= 100

buf0	= $2010
buf1	= $4010

/*-------------------------------------------------------------------------------------------------*/

	org $80

regA	.ds 1
regX	.ds 1
regY	.ds 1

cnt	.ds 1
line	.ds 1

/*-------------------------------------------------------------------------------------------------*/

	.get 'monster.dat',-9		; palette

/*-------------------------------------------------------------------------------------------------*/

	org buf0
	ins 'monster.dat',0,8000

	org buf1
	ins 'monster.dat',$2800,8000

/*-------------------------------------------------------------------------------------------------*/

		.align $100
	dlist0:	dta d'pp',$10+$80
		dta $10				; 2 linie dla pierwszej zmiany koloru przez IRQ
		:200 dta $4e,a(buf0+#*40)
		dta $41,a(dlist1)

		.align $200
	dlist1:	dta d'pp',$10+$80
		dta $10
		:200 dta $4e,a(buf1+#*40)
		dta $41,a(dlist0)

/*-------------------------------------------------------------------------------------------------*/

main	lda:cmp:req 20

	sei
	mva	#$00	nmien
	sta	irqen

	mva #height	line
	
	mva	#$fe	portb

	mwa	#dlist0	dlptr		; pierwsz klatka, potem juz ANTIC bedzie przelaczal

	mwa	#NMI	$fffa
	mwa	#irq	$fffe		; setup custom IRQ handler

	mva	#3	SKCTL

	mva	#1	AUDCTL		; 0=POKEY 64KHz, 1=15KHz

	mva	#0	AUDC4		; test - no polycounters + volume only
	mva	#0	AUDF4		; line-1 (0 = 1 line)

	mva	#$c0	nmien
	cli

	jmp *


/*-------------------------------------------------------------------------------------------------*/

	.align

	.pages

IRQ	.local
	sta regA

	mva #.get[1] color0
	mva #.get[2] color1
	mva #.get[3] color2

	mva #0 irqen
	mva #4 irqen

	mva <IRQ2 irqvec

	lda regA
	rti
	.endl

	
IRQ2	.local
	sta regA

	mva #.get[5] color0
	mva #.get[6] color1
	mva #.get[7] color2

	mva #0 irqen
	mva <IRQ irqvec

	dec line
	seq

	mva #4 irqen

	lda regA
	rti
	.endl

	.endpg


NMI	bit nmist
	bpl vbl


dli0	sta regA

	lda #4
	sta stimer
	sta irqen

	lda regA
	rti


vbl	sta nmist
	sta regA
	stx regX
	sty regY

	mva #$22	dmactl

	mva #height	line
	
	lda #0
sw	equ *-1
	eor #1
	sta sw
	beq _0

	mwa #irq2 $fffe
	bne skp
	
_0	mwa #irq $fffe

skp
	mva #.get[0]	colbak
	mva #.get[1]	color0
	mva #.get[2]	color1
	mva #.get[3]	color2	

	lda regA
	ldx regX
	ldy regY
	rti

	run main

Przykład wyświetlenia obrazka MCPP (160x100x16) używając IRQ.

	icl 'atari.hea'


height	 = 100

bmp	= $2010

/*-------------------------------------------------------------------------------------------------*/

	org $80

regA	.ds 1
regX	.ds 1
regY	.ds 1

cnt	.ds 1
line	.ds 1

/*-------------------------------------------------------------------------------------------------*/

	.get 'robots.mcpp',-8		; palette

/*-------------------------------------------------------------------------------------------------*/

	org bmp

	.rept 100
	ins 'robots.mcpp',4000+#*40,40
	ins 'robots.mcpp',#*40,40
	.endr

/*-------------------------------------------------------------------------------------------------*/

	.align $100

	dlist0:	dta d'pp',$10+$80
		dta $10				; 2 linie dla pierwszej zmiany koloru przez IRQ
		:200 dta $4e,a(bmp+#*40)
		dta $41,a(dlist0)

/*-------------------------------------------------------------------------------------------------*/

main	lda:cmp:req 20

	sei

	mva	#$00	nmien
	sta	irqen

	mva	#height	line
	
	mva	#$fe	portb

	mwa	#dlist0	dlptr		; poczatkowa klatka, potem juz ANTIC bedzie przelaczal katki

	mwa	#NMI	nmivec
	mwa	#irq	irqvec		; setup custom IRQ handler

	mva	#3	SKCTL

	mva	#1	AUDCTL		; 0=POKEY 64KHz, 1=15KHz

	mva	#0	AUDC4		; test - no polycounters + volume only
	mva	#1	AUDF4		; ~64KHz clock 16 = ~4Khz timer, ~15KHz clock 4 = ~4KHz

	mva	#$c0	nmien
	cli


	jmp *


/*-------------------------------------------------------------------------------------------------*/

	.align

IRQ	.local
	sta regA

_1	mva #.get[4] color0
	mva #.get[5] color1
	mva #.get[6] color2

	mva #0 IRQEN
	mva #4 IRQEN

	#cycle #13

	dec line
	beq IRQstop

	mva #.get[0] color0
	mva #.get[1] color1
	mva #.get[2] color2

	lda regA
	rti

IRQstop	mva #0 IRQEN

	lda regA
	rti

	.endl


NMI	bit nmist
	bpl vbl


dli0	sta regA

	lda #4
	sta wsync
	sta stimer
	sta irqen

	lda regA
	rti


vbl	sta nmist
	sta regA
	stx regX
	sty regY

	mva #scr40	dmactl

	mva #height line

	lda regA
	ldx regX
	ldy regY
	rti

	run main

Tebe/Madteam

 

madteam.atari8.info © MadTeam, hosted: www.atari8.info