1

Temat: szybkie wektory na przerwaniu pokeya

witam,
od jakiegoś czasu piszę prockę do szybkich wektorów dla rozdzielczości 128/120 i mam mały problem z Altirrą (albo z kodem),
na Atari800win wszystko śmiga, Altirra zachowuje się tak jakby w ogóle nie dochodziło do przerwań

robię tak:
1.ustawiam 6 bit w $d208 dla przerwania 1 pokeya.
2.Ustawiam AUDCTL i AUDF.
3.przed skokiem do procedury rysującej ustawiam adres procki przerwania w $fffe-f
4.wpisuję wartość dowolną w $d209

w proc. IRQ wpisuje ponownie wartość dowolną do $d209, przerwania w procedurze rysującej wywołuje przez

 
...
cli
sei ;(poprawiono)
...

plik .obx w załączniku

Ostatnio edytowany przez gorgh (2011-08-18 16:42:32)

Post's attachments

fastlinecop.obx 11.65 kb, liczba pobrań: 14 (od 2011-08-18) 

Tylko zalogowani mogą pobierać załączniki.

2

Odp: szybkie wektory na przerwaniu pokeya

jeżeli dobrze pamiętam po każdym wystąpieniu przerwania IRQ od POKEY-a trzeba skasować bit odpowiadający za wystąpienie przerwania w IRQEN ($d20e) a następnie ustawić bit ponownie. Chodzi o potwierdzenie odebrania przerwania oraz dopuszczenie następnego przerwania.

nie bardzo rozumiem gdzie masz to SEI i CLI.

STIMER ($D209) nie trzeba zapisywać w procedurze przerwania. Można to zrobić tylko raz po ustawieniu wektorów i IRQEN ($d20e).




pozdrawiam
Seban

Ostatnio edytowany przez seban (2011-08-18 16:43:36)

3

Odp: szybkie wektory na przerwaniu pokeya

Z tego co piszesz nie ustawiasz rejestru zezwolenia na przerwanie IRQEN ($D20E) wartością zezwalającą na przerwanie TIMER1 (#1).
SEI powoduje zablokowanie obsługi przerwań przez CPU, a CLI odblokowanie obsługi ale tylko tych, które są dozwolone w IRQEN. W żadnym wypadku NIE WYGENERUJE żadnego przerwania.
IRQST ($D20E) zawiera flagi informujące, że dane źródło przerwania IRQ jest aktywne. Poprawna obsługa przerwania polega na zablokowaniu i ponownym odblokowaniu przerwania w IRQEN dzięki czemu zniknie flaga zgłoszenia w IRQST.

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

4

Odp: szybkie wektory na przerwaniu pokeya

dzięki za odpowiedzi, oczywiście jak zwykle zapomniałem dodać, że w proc. przerwania najpierw kasuje a potem ustawiam na #1 $d20e, samo przerwanie wywołuje zaś nie cli sei a sei cli , zaraz to poprawie
@Seban:
cli/sei używam w pętli rysującej 1 z 8 podstawowych linii, w przerwaniach dodaje dodatkowe przesunięcia tak, że z 8 linii powstaje mi 58 na każdą ćwiartkę okręgu.

Panowie, jakieś jeszcze inne sugestie, co tu może źle działać?

Ostatnio edytowany przez gorgh (2011-08-18 16:49:27)

5

Odp: szybkie wektory na przerwaniu pokeya

Ale rozkazy SEI i CLI, ani żadna ich kombinacja nie powodują wygenerowania przerwania, a jedynie ustawienie CPU w stan kiedy może już przyjmować zgłoszenia przerwań i je obsługiwać (CLI) lub kiedy ich nie będzie obsługiwać (SEI). Dlatego te przerwania nazywają się maskowalne.

Edit: Wygenerowanie przerwania odbywa się po odliczeniu licznika AUDF1 ($D200) od ustawionej wartości do zera. Rozpoczęcie odliczania następuje po wpisaniu dowolnej wartości do STIMER ($D209).

Ostatnio edytowany przez mono (2011-08-18 16:48:37)

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

6

Odp: szybkie wektory na przerwaniu pokeya

mono, czy w takim razie jeśli wygenerowany zostaje sygnał przerwania po odliczeniu $d200 to procesor "czeka" aż zostanie umożliwione przerwanie irq czy w przypadku gdy nie jest ono możliwe po prostu ignoruje go? czy sygnał w procesorze jest sutawiony dopóki przerwanie się nie odbędzie?

Ostatnio edytowany przez gorgh (2011-08-18 16:52:48)

7

Odp: szybkie wektory na przerwaniu pokeya

atari800win - sieka

altirra wykonuje w kolo macieja ten kod:

AC00: A9 00            LDA #$00
AC02: 8D 0E D2         STA IRQEN
AC05: E8               INX
AC06: BD 00 B0         LDA $B000,X
AC09: 85 FE            STA $FE
AC0B: BD 00 B1         LDA $B100,X
AC0E: 85 FF            STA $FF
AC10: A9 01            LDA #$01
AC12: 8D 0E D2         STA IRQEN
AC15: 8D 09 D2         STA STIMER
AC18: 40               RTI
przechodze na tumiwisizm

8

Odp: szybkie wektory na przerwaniu pokeya

Hej!

to może ja się wtrącę... przykładowy kod działający na real Atari i pod Altirrą :) (brzydki i nieładnie napisany ,ale działa ;] chodzi tylko o przykład jak może wyglądać działająca procedura obsługi POKEY-owego timera)

        opt    h+
        org    $a000
    
st      sei                 ; disable IRQ
        inc    $d40e        ; disable NMI
        lda    $d40b        ; wait for vertical sync
        bne    *-3
        sta    $d400        ; turn off screen!

        lda    #$fe        ; turn off OS-ROM!
        sta    $d301

        ldx    <irq        ; set new IRQ vector
        ldy    >irq
        stx    $fffe
        sty    $ffff
    
        lda    #$03        ; init POKEY
        sta    $d20f
    
        lda    #$00        ; set timer freq
        sta    $d208
    
        lda    #$00        ; set channel #0 volume
        sta    $d201
    
        lda    #$7e        ; set time #0 frequency
        sta    $d200
        
        lda    #$01        ; enabnle TIMER0 IRQ
        sta    $d20e
        sta    $d209       ; reset timers!
    
        cli            ; enable IRQ
        jmp    *        ; loop! :)
    
irq        sta    reg_A+1        ; save A reg.

val        lda    #$08        ; change border color!
        sta    $d01a
        eor    #$38
        sta    val+1
    
        lda    #$00        ; clear IRQ status!
        sta    $d20e        
        lda    #$01        ; enable timer #0 IRQ
        sta    $d20e

reg_A        lda    #$00        ; restore A reg.
        rti            ; return from iterrupt!
    
        run    st        ; RUN vector
        
        
    

Ostatnio edytowany przez seban (2011-08-18 17:09:46)

9

Odp: szybkie wektory na przerwaniu pokeya

to może jeszcze mała prośba, z racji tego, że jestem na wczasach nie mam możliwości sprawdzenia, czy prawdziwy sprzęt zachowuje się tak jak Altirra, może ktoś potwierdzić lub zaprzeczyć?

10

Odp: szybkie wektory na przerwaniu pokeya

Procesor zajmuje się wykonywaniem Twojego programu. W momencie kiedy pojawi się sygnał przerwania ustawiana jest odpowiednia flaga żądania obsługi w IRQST. Jeśli znacznik I procesora jest zgaszony (a gasi go rozkaz CLI), wtedy wykonywanie programu jest zawieszane, a CPU zajmuje się wykonaniem procedury obsługi przerwania. Po wykonaniu obsługi wraca z powrotem do wykonywania programu od miejsca w którym mu przerwano.
Jeśli znacznik I jest ustawiony, to CPU nie wykonuje przerwania. Do chwili kiedy nie skasujesz flagi I po prostu przerwania nie będą obsługiwane, ale odpowiednie znaczniki ciągle będą się palić w IRQST. Jak odblokujesz przerwania (CLI), wtedy procesor będzie ciągle przerywał Twój program i będzie obsługiwał przerwania do chwili kiedy w IRQST nie zniknie ostatnie żądanie. Żądanie obsługi przerwania znika kiedy następuje potwierdzenie jego obsługi - odbywa się to przez Twoją procedurę obsługi przerwania w sposób, jaki opisano wyżej - przez zablokowanie danego przerwania w IRQEN i ponowne jego włączenie w tym samym rejestrze.

Edit: Jeśli źródło przerwań zgłasza je często (TIMER1 może to robić BARDZO często - szczególnie z ustawionym zegarem 1.77MHz), może się zdarzyć, że podczas obsługi przerwania nadejdzie nowe żądanie. Wtedy po zakończeniu obsługi bieżącego przerwania CPU od razu wejdzie z powrotem do procedury obsługi przerwania.

Ostatnio edytowany przez mono (2011-08-18 17:08:03)

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

11

Odp: szybkie wektory na przerwaniu pokeya

mono napisał/a:

Rozpoczęcie odliczania następuje po wpisaniu dowolnej wartości do STIMER ($D209).

No własnie w/g mnie nie trzeba wcale STIMER ustawiać :) Nigdy tego nie robiłem i zawsze działało :) STIMER jedynie inicjuje liczniki POKEY-a wartościami wpisanymi do AUDFx. Pokey i tak przeładowuje sam liczniki gdy doliczy do zera. Nie widzę sensu/potrzeby używania STIMER.

12

Odp: szybkie wektory na przerwaniu pokeya

czyli jednym słowem procesor nie wygeneruje przerwania w krótkiej chwili pomiędzi cli/ sei jeżeli w tym momencie nie dostanie sygnału przerwania z pokeya, który to sygnał się nie utrzymuje "na linii" a chwilowo jest wysyłany
kurde, z tego co widze to raczej ta procka nie zadziała

13

Odp: szybkie wektory na przerwaniu pokeya

Nie ma przerwań IRQ, które są chwilowo wysyłane. Żądanie IRQ utrzymuje się do chwili, aż je zgasisz. Przez potwierdzenie odebrania przerwania.

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

14

Odp: szybkie wektory na przerwaniu pokeya

czyli teoretycznie jeżeli wysłany jest sygnał przerwania to CLI  POWINNO "spowodować skok" do procedury przerwania, tak? nic już nie rozumiem :/

Ostatnio edytowany przez gorgh (2011-08-18 17:19:14)

15

Odp: szybkie wektory na przerwaniu pokeya

Tak.

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

16

Odp: szybkie wektory na przerwaniu pokeya

UFFF,czyli jednak robię to dobrze dzięki ludziska, jutro sprawdzę na Atarynce jak to wygląda i poszukam ew. błędu

17

Odp: szybkie wektory na przerwaniu pokeya

znaczy nie bardzo rozumiem co chcesz osiągnąć w taki sposób :) tzn. nie bardzo rozumiem sens tego cli/sei i dodatkowo zatrudnienie licznika POKEY ;) Nie patrzyłem dokładnie w twój kod ale nie zachowujesz wartości rejestrów procesora które zmieniasz podczas przerwania. Po powrocie z przerwania rejestry które zmieniłeś podczas procedury przerwania, będą miały wartość którą pozostawiła procedura przerwania. Jeżeli w tzw. "ciągu głównym" wykorzystujesz którykolwiek ze zmienianych rejestrów wyjdzie totalny chaos :) Jeżeli to celowe działanie z jakiegoś powodu to OK, zaznaczam to tylko abyś był tego świadom :)

Ostatnio edytowany przez seban (2011-08-18 17:29:50)

18

Odp: szybkie wektory na przerwaniu pokeya

tak, jest to celowe, akumulator jeżeli procka jest wywoływana po CLI nie gra roli, a rejestry X i Y są potrzebne do procki rysującej, zarzucam przykładowy kod:

rbyte3      ; \ minus 40-32 w stronę pionu
  cli
  sei
  lda #0
  clc
  adc tab2,x
  sta $f2
  lda ($f2),y
  ora tab3,x
  sta ($f2),y
  dex
rb32
  lda #$20
  adc tab2,x
  sta $f2
  lda ($f2),y
  ora tab3,x
  sta ($f2),y

rb33
  lda #$40
  adc tab2,x
  sta $f2
  lda ($f2),y
  ora tab3,x
  sta ($f2),y
  dex
rb34
  lda #$60
  adc tab2,x
  sta $f2
  lda ($f2),y
  ora tab3,x
  sta ($f2),y 
rb35
  cli
  sei
  lda #$80
  adc tab2,x
  sta $f2
  lda ($f2),y
  ora tab3,x
  sta ($f2),y
rb36
  lda #$a0
  adc tab2,x
  sta $f2
  lda ($f2),y
  ora tab3,x
  sta ($f2),y 
  dex
rb37
  lda #$c0
  adc tab2,x
  sta $f2
  lda ($f2),y
  ora tab3,x
  sta ($f2),y
rb38
  lda #$e0
  adc tab2,x
  sta $f2
  lda ($f2),y
  ora tab3,x
  sta ($f2),y 
rbyte3loop
 inc $f3
 dec $f5
 bne rbyte3
 sei
 rts

i procka IRQ:

irq2r lda #0  ; byte1,byte2 dla byte3,byte4-7 reversed
 sta $d20e
 dex
 lda #1
 sta $d20e
 sta $d209
 rti

edit: być może błąd jest spowodowany wywołaniem przerwania poza procką rysującą, wtedy rejestry mogą się mieszać

Ostatnio edytowany przez gorgh (2011-08-18 17:42:46)

19

Odp: szybkie wektory na przerwaniu pokeya

prawdę mówiąc nie mam pojącia kiedy się wykona IRQ po CLI jeżeli było przerwanie od timer-a pokey. Nie bardzo również rozumiem twoją koncepcję i po co wywoływać IRQ dla jednego DEX, bardzo dużo cykli tracisz na taką całą skomplikowaną procedurę :) Być może po prostu nie pojmuję koncepcji i pomysłu co chcesz zrobić.. to ma być jakieś dziwne drawto?

20

Odp: szybkie wektory na przerwaniu pokeya

tak, drawto. akurat tu tego nie widać ale mierząc cyklami to ta procka będzie szybsza od drawto z paczki MADS o jakieś 25 %, w niektórych przypadkach nawet 40-50 %. niestety gorzej będzie z tego co się zorientowałem z precyzją , ale coś za coś

Ostatnio edytowany przez gorgh (2011-08-18 19:37:04)

21

Odp: szybkie wektory na przerwaniu pokeya

nie wiem co jest w pakiecie MADS, ale nie wydaje mi się możliwe aby coś ze zgłaszaniem IRQ mogło być szybsze niż zoptymalizowana procedura wykonana w ciągu głównym bez użycia przerwań.

Ostatnio edytowany przez seban (2011-08-18 20:22:14)

22

Odp: szybkie wektory na przerwaniu pokeya

tutaj pomysł jest taki, że w pętli stawia się punkty bez liczenia tego czy przesunąć pixel w bok czy nie za każdym razem jak to jest w algorytmie bresenhama, za coś takiego odpowiada odpowiednio często wywoływane przerwanie, to z grubsza pomysł na tą prockę

23

Odp: szybkie wektory na przerwaniu pokeya

A nie prościej jsr?

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

24

Odp: szybkie wektory na przerwaniu pokeya

możesz rozwinąć wypowiedź ?:)

25

Odp: szybkie wektory na przerwaniu pokeya

Jeśli w ciągu głównym liczysz współrzędne punktów, a za pomocą cli, sei pozwalasz na wykonanie procedury IRQ, która w międzyczasie nadeszła, to może prościej (i szybciej) byłoby wywołać zwykły jsr bez uruchamienia przerwań. Przyjęcie procedury przerwania wymaga:
- zakończenia bieżącego cyklu rozkazowego (czyli cli) - rozkaz sei pobrany prefetchem podczas wykonania cli zostaje zignorowany,
- przyjęcia przerwania przez cpu - 7 cykli (odłożenie powrotu i rejestru znaczników cpu na stos, wstawienie adresu procedury obsługi przerwania z $fffe do pc),
- przy powrocie z przerwania rti wykona się drugie 7 cykli.
A jsr zajmie 6 cykli + 6 cykli rts, nie komplikuje algorytmu, jest przejrzystsze.

Edit: A jeśli już koniecznie chcesz użyć przerwań, to zrób zamiast cli, sei po prostu brk!

Ostatnio edytowany przez mono (2011-08-18 20:47:18)

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje