![]() |
|
Start | Super Packer | Atari Graphics Studio | Graph2Font | Mads | MadPascal | YouTube | http://madteam.atari8.info |
Tebe/Madteam
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. Więcej o przerwaniu IRQ dla trybu 9++, HIP w tym wątku http://www.atari.org.pl/forum/viewtopic.php?id=13292 Wątek na AtariAge https://atariage.com/forums/topic/149957-timer-irqs-as-dlis-tutorial/ 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 co drugą linię obrazu, oszczędzamy najwięcej cykli CPU. 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 |