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

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

Post's attachments

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

Tylko zalogowani mogą pobierać załączniki.

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

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

3

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 Ostatnio edytowany przez gorgh (2011-08-18 16:49:27)

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ć?

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

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).

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

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

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?

7

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 Ostatnio edytowany przez seban (2011-08-18 17:09:46)

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
        
        
    

9

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 Ostatnio edytowany przez mono (2011-08-18 17:08:03)

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.

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

11

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

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

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 Ostatnio edytowany przez gorgh (2011-08-18 17:19:14)

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

15

Tak.

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

16

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

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

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 :)

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

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ć

19

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 Ostatnio edytowany przez gorgh (2011-08-18 19:37:04)

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ś

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

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ń.

22

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

A nie prościej jsr?

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

24

możesz rozwinąć wypowiedź ?:)

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

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!

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