Autor Wątek: Interfejs generujący przerwania maskowalne w trybie 2  (Przeczytany 7896 razy)

silenter

  • *****
  • Wiadomości: 1337
  • Miejsce pobytu:
    Warszawa/Radzymin
Czy któryś z kolegów  projektował interfejsy z wykorzystaniem tego trybu przerwań.
Mam zamiar podłączyć ATMEGę do spectruma i mam zamiar wykorzystać przerwania 2 typu do komunikacji.
Na razie  studiuję książkę "Układy mikroprocesorowe Z80", ale chętnie skorzystałbym z doświadczeń osób które mają jakieś doświadczenie w tym względzie. Pewnie będę musiał zrobić jakiś dekoder adresowy i system wykrywania stanu kilku linii sterujących.
Pewnie skończy się jakimś GALem albo CPLD.
128k +2 UK issue 1, JS128, FDD3000 in restoration, ZAXON MGT +D, PEAR AmpY, Pear ExEar :), PEAR TI-OF-TTL+FDD35, co to tu robi??? => 2xCDTV&A500

https://soundcloud.com/silenter

https://www.youtube.com/channel/UCKZhL7Lq1zUDDnRDTJKhN4A

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4540
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #1 dnia: 2017.05.15, 21:15:50 »
Jestem ciekaw czy w ogóle takie urządzenie będzie działać z ZXem. Spekuluję tylko, że ULA nie da się łatwo i będzie siać po szynie...

silenter

  • *****
  • Wiadomości: 1337
  • Miejsce pobytu:
    Warszawa/Radzymin
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #2 dnia: 2017.05.15, 21:22:35 »
Z dawnych doświadczeń pamiętam, że z ULĄ lepiej nie walczyć tylko się w nią "wsłuchać".
128k +2 UK issue 1, JS128, FDD3000 in restoration, ZAXON MGT +D, PEAR AmpY, Pear ExEar :), PEAR TI-OF-TTL+FDD35, co to tu robi??? => 2xCDTV&A500

https://soundcloud.com/silenter

https://www.youtube.com/channel/UCKZhL7Lq1zUDDnRDTJKhN4A

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #3 dnia: 2017.05.16, 08:08:35 »
Na pewno wywoływanie przerwań z zewnątrz jest możliwe. Ale nie wydaje mi się, żeby sam interfejs był w stanie zgadnąć w którym trybie znajduje się procesor - musiałby słuchać od resetu, detektować M1, sprawdzać co jest wtedy na szynie danych, czekać na następny bajt (bo IM 0/IM 1/IM 2 są prefiksowane ED) i dopiero jak wykryje, że procesor jest w trybie 2 mógłby zacząć generować przerwania.
Prostszym rozwiązaniem będzie dorobienie w hardwarze jakiegoś triggera (port, adres w ROMie itp.), który będzie aktywował mechanizm generowania przerwań i w softwarze włączanie po uruchomieniu trybu 2 a wyłączanie przed przejściem do innego. No i oczywiście jakiś port, który pozwoli odróżnić przerwanie ULA od twojego przerwania.

silenter

  • *****
  • Wiadomości: 1337
  • Miejsce pobytu:
    Warszawa/Radzymin
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #4 dnia: 2017.05.16, 08:52:31 »
Ja to myślałem tak.
1) Wgrywamy do ZX soft który sprawdza czy interfejs jest podłączony - jeśli tak to przełącza przerwania maskowalne w tryb 2.
2) Wystawia outem jakiś status który uaktywnia interfejs
3) interfejs kiedy potrzebuje wysłać lub odebrać dane z ZXa generuje przerwanie maskowlne typu 2 i na port danych wystawia młodszy bajt wektora przerwania
4) soft dostaje info o potrzebie komunikacji z interfejsem i komunikuje się już normalnie przez in out - więc nie ma problemu jeżdżenia po szynie - tu wymyślę jakiś protokół wymiany danych.
---------------------------
Nie jestem pewien czy w stanie "suchym" ULA generuje jakieś przerwania maskowalne bo NMI sieje gęsto i często - a nawet jeśli to tylko muszę znaleźć wolny wektor.
Wektorów jest 127 bo zalecane jest żeby najmłodszy bit był zawsze zerem.
Muszę podłączyć się analizatorem pod szynę i obadać co tam się dzieje.
128k +2 UK issue 1, JS128, FDD3000 in restoration, ZAXON MGT +D, PEAR AmpY, Pear ExEar :), PEAR TI-OF-TTL+FDD35, co to tu robi??? => 2xCDTV&A500

https://soundcloud.com/silenter

https://www.youtube.com/channel/UCKZhL7Lq1zUDDnRDTJKhN4A

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #5 dnia: 2017.05.16, 09:15:12 »
Ja to myślałem tak.
1) Wgrywamy do ZX soft który sprawdza czy interfejs jest podłączony - jeśli tak to przełącza przerwania maskowalne w tryb 2.
2) Wystawia outem jakiś status który uaktywnia interfejs

Czyli mniej więcej tak jak napisałem.

Cytuj
3) interfejs kiedy potrzebuje wysłać lub odebrać dane z ZXa generuje przerwanie maskowlne typu 2 i na port danych wystawia młodszy bajt wektora przerwania

Można i tak, choć to powoduje, że musisz mieć dwie procedury obsługi przerwań a do tego jak podłączysz coś jeszcze, do szyny, co może wystawiać (choćby przez przypadek) swoje wektory to może się zdarzyć, że strzeli akurat tym twoim. Prawdopodobieństwo jest niewielkie, ale jednak jest - moim zdaniem wywołanie przerwania i wystawienie na porcie znacznika (np. normalnie 0 a po przerwaniu 1 i zerowane odczytem) upraszcza konstrukcję oprogramowania. Masz wtedy jedną procedurę dla wszystkich przerwań np taką:

  push af
  in a,(PORT_STATUSU)
  or a
  jr nz, obsługa_komunikacji
  pop af
  ei
  reti

obsługa_komunikacji:
;  reszta twojego kodu
  ei
  reti

Cytuj
4) soft dostaje info o potrzebie komunikacji z interfejsem i komunikuje się już normalnie przez in out - więc nie ma problemu jeżdżenia po szynie - tu wymyślę jakiś protokół wymiany danych.

Ale chcesz tą komunikację robić w procedurze obsługi przerwań? A ile tych danych chcesz wymieniać? I co jeszcze poza samą komunikacją chcesz robić? Jeśli danych będzie dużo, to trzeba jeszcze pomyśleć o jakimś kolejkowaniu przerwań po stronie interfejsu i ich blokowaniu tak, żeby ci nie generował następnego przerwania przed zakończeniem pierwszego. No i jeśli chciałbyś robić coś więcej niż tylko komunikację to dobre by było, żeby został jakiś czas poza obsługą przerwań - zakładam, że chcesz robić coś więcej, bo inaczej po co byłoby to robić na przerwaniach? ;)

Cytuj
Nie jestem pewien czy w stanie "suchym" ULA generuje jakieś przerwania maskowalne bo NMI sieje gęsto i często - a nawet jeśli to tylko muszę znaleźć wolny wektor.

Ymmm... Nie rozumiem pytania i tego co napisałeś... ULA generuje IRQ raz na ramkę obrazu czyli mniej więcej 50 razy na sekundę. I nie generuje żadnych przerwań NMI (zwłaszcza, że w standardowych warunkach generowanie NMI albo nie robi nic albo resetuje komputer).

Cytuj
Wektorów jest 127 bo zalecane jest żeby najmłodszy bit był zawsze zerem.

Eeee... To jest tylko taka sugestia - nie ma obowiązku ustawiania parzystego wektora ;) Tyle, że przy standardowych przerwaniach ULA wektor zwykle będzie ustawiony na FF i tam też musisz mieć procedurę obsługi przerwania (choćby zwykłe EI/RETI).

silenter

  • *****
  • Wiadomości: 1337
  • Miejsce pobytu:
    Warszawa/Radzymin
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #6 dnia: 2017.05.16, 13:51:30 »
Nie jestem pewien w jakim trybie przerwań chodzi ula ULA.

W trybie drugim bez problemu obsługuje się wszystkie podłączone urządzenia i podprogramy.

pamiętajmy że urządzenie wystawia tylko młodzsy bajt wektora przerwania starszy bajt jest przechowywany w rejestrze I.
Przy starcie systemu ustawiony jest na adres 0.

Każde urządzenie używające trybu 2 powinno działać następująco

1) nie powinno wywoływać przerwań do czasu gdy nie jest pewne, że podprogramy obsługi jego przerwań zostały załadowane (to właśnie odczytujemy z rejestru statusowego w interfejsie)

2) program obsługujący przerwania po załoadowaniu musi zapamiętać stan rejestru I w pamięci i wstawić własny adres obsługi przerwania do rejestru I .
Dodatkowo trzeba odpowiednio wypełnić tablicę wektorów przerwań.
Robimy to w ten sposób, że dla wektora który będzie obsługiwał nasze urządzenie dajemy skok do procedury obsługi urządzenia a WE WSZYSTKICH INNYCH PRZYPADKACH
skaczemy pod adres zapamiętany z rejestu I + wektor.

Jeśli wszyscy zgodnie z tą metodologią postępują to nie następuje problem konfliktów przerwań (podprogramy wywołują się kaskadowo).
Jeszcze jedną zasadą jest aby tablicę wektorów przerwań inicjować poleceniem  RETI (znaczy się tam gdzie do tej pory nie było obsługiwanych przerwań).
RETI Zajmuje 2 bajty - z tego właśnie wynika zalecenie ustawianie najniższego bitu w wektorze na 0.
Jeśli wszystkie procedury obsługi przerwań będą działać w ten sposób to każdy nowy podprogram jest wstanie przeczytać aktualną tablicę i znaleźć wolny nr. przerwania.
Taki nr. można wpisać do rejestu statusowego urządzenia i urządzenie będzie się zachowywać "inteligentnie" w systemie do czasu do kiedy będą wolne przerwania.

Tyle idea przerwań maskowalnych w trybie 2 w Z80 - na ile sprzęt i software w ZXach trzyma się zasad - zobaczymy.

Pobadam sobie w symulatorze jak ULA zachowuje się odnośnie przerwań.

128k +2 UK issue 1, JS128, FDD3000 in restoration, ZAXON MGT +D, PEAR AmpY, Pear ExEar :), PEAR TI-OF-TTL+FDD35, co to tu robi??? => 2xCDTV&A500

https://soundcloud.com/silenter

https://www.youtube.com/channel/UCKZhL7Lq1zUDDnRDTJKhN4A

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #7 dnia: 2017.05.16, 14:27:48 »
Nie jestem pewien w jakim trybie przerwań chodzi ula ULA.

Tryb obsługi przerwań nie ma dla ULA żadnego znaczenia - generuje przerwanie ramki i nic więcej. I w momencie generowania tego przerwania nie wystawia na szynę żadnych wektorów. Dlatego w Spectrum nie da się używać trybu 0 a w trybie 2 trzeba mieć tablicę wektorów przygotowaną w "sprytny" sposób.

Cytuj
W trybie drugim bez problemu obsługuje się wszystkie podłączone urządzenia i podprogramy.

...CIACH opis działania przerwań...


I to wszystko jest bardzo fajne pod warunkiem, że wykluczysz ULA i brak podawania czegokolwiek na szynę oraz fakt, że po podłączeniu jakichś "dzikich" urządzeń może się zdarzyć, że w momencie generowania IRQ przez ULA na szynie znajduje się coś nieprzewidzianego. Albo, że twoje urządzenie pogryzie się z ULA w kwestii generowania samego IRQ.

Cytuj
Jeszcze jedną zasadą jest aby tablicę wektorów przerwań inicjować poleceniem  RETI (znaczy się tam gdzie do tej pory nie było obsługiwanych przerwań).
RETI Zajmuje 2 bajty - z tego właśnie wynika zalecenie ustawianie najniższego bitu w wektorze na 0.

Ymmm... Nie ma związku między długością RETI a zaleceniem parzystości wektora (a w każdym razie ja się nigdy nie spotkałem w żdnych materiałach z taką sugestią). Z80 Manual twierdzi, że bit zero wektora ma być zerowy, ale procesor zachowuje się całkowicie poprawnie jeśli nie jest. RETI tak na prawdę jest zwykłym RETem z punktu widzenia programu a jedyna różnica jest taka, że urządzenia zewnętrzne z rodziny Z80 (SIO, CTC etc.) potrafią wykryć wykonanie RETI i przy odpowiedniej konstrukcji sprzętu umożliwiają spięcie kilku takich urządzeń z różnymi priorytetami przerwań.

I wszystko to w zasadzie nie ma praktycznego zastosowania w Spectrum bo... ULA. Sygnał przerwania jest generowany przez ULA w trakcie generowania ramki ekranu co oznacza, że na szynie nie ma "pływających atrybutów" a to oznacza, że procesor odczytuje w takiej sytuacji z szyny wartość 255 - zdecydowanie nieparzystą ;)

Cytuj
Tyle idea przerwań maskowalnych w trybie 2 w Z80 - na ile sprzęt i software w ZXach trzyma się zasad - zobaczymy.

Pobadam sobie w symulatorze jak ULA zachowuje się odnośnie przerwań.

Ale tu nie ma czego "zobaczać" - od "prawie zawsze" wiadomo jak ULA się zachowuje i jak zachowują się przerwania.

Cytat ze stosownego rozdziału ULA Book'a:
Cytuj
The ULA does not place an instruction or vector address on the data bus when it generates the processor interrupt, so interrupt mode 0 cannot generally be used with the ZX Spectrum. Interrupt mode 2, on the other hand, can be used if the vector table is carefully constructed to return the same 16 bit address regardless of which pair of bytes are taken; therefore making the value on the data bus at the time the interrupt was generated irrelevant.

I szczerze mówiąc nie słyszałem o urządzeniach zewnętrznych dla ZXS, które używałyby do czegokolwiek przerwań w trybie 2 - z jednego prostego powodu: jeśli urządzenie ma rozszerzać normalne zastosowanie to musi umieć współpracować z BASICem a co za tym idzie musi umieć pracować w standardowym dla Spectrum trybie 1.

Cała twoja koncepcja zamknie się w tym, że twoje urządzenie musi umieć się dogadać z tym co zastanie a soft musi umieć się do tego dostosować i potrafić odbierać oba przerwania - w tym takie, przy którym stan szyny danych może być niezdefiniowany.

silenter

  • *****
  • Wiadomości: 1337
  • Miejsce pobytu:
    Warszawa/Radzymin
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #8 dnia: 2017.05.16, 15:48:28 »
I to wszystko jest bardzo fajne pod warunkiem, że wykluczysz ULA i brak podawania czegokolwiek na szynę oraz fakt, że po podłączeniu jakichś "dzikich" urządzeń może się zdarzyć, że w momencie generowania IRQ przez ULA na szynie znajduje się coś nieprzewidzianego. Albo, że twoje urządzenie pogryzie się z ULA w kwestii generowania samego IRQ.

Muszę poczytać o ULA - terra incognita poza paroma ogólnikami.

Sygnał przerwania jest generowany przez ULA w trakcie generowania ramki ekranu co oznacza, że na szynie nie ma "pływających atrybutów" a to oznacza, że procesor odczytuje w takiej sytuacji z szyny wartość 255 - zdecydowanie nieparzystą ;)
Jak to w ZXie - poszybkości po taniości - dobre praktyki tylko tam gdzie nie zwiększały kosztów.

I szczerze mówiąc nie słyszałem o urządzeniach zewnętrznych dla ZXS, które używałyby do czegokolwiek przerwań w trybie 2 - z jednego prostego powodu: jeśli urządzenie ma rozszerzać normalne zastosowanie to musi umieć współpracować z BASICem a co za tym idzie musi umieć pracować w standardowym dla Spectrum trybie 1.
Tryb 1 jest do kitu w ZX bo zawsze ląduje w 0x66 czyli w ROMie. Wiem, że interfejsy podmieniają ROM i wtedy mogą przechwytywać przerwania.
Dla mnie tryb 2 jest zdecydowanie najatrakcyjniejszy bo daje możliwość umiesczenia się z programem gdziekolwiek w ramie.
Swoją drogą nie widzę dla swojego interfeju zastosowań basicowych.

Wyobraźmy sobie że podłączam  jakiś timer przez interfejs. Basicem ładuję mu czas. i startuję. Timer dochodzi do zera i co wywyołuje RST a procesor zaczyna wykonywać podprogram
0x66?? bez sensu. Timer powinien wywołać np. INT_0x20 a tam już powinna siedzieć procedura obsługi przerwania timera - proste jak drut. Basic nie ma tu nic do rzeczy.
W sofcie muszę wykryć przerwanie od ULI np. poprzez zpięcie się na INT_0xFF i zrobić jp 0x66.

W interfejsie musze co prawda zrobić kontrolę wywołania przerwania przez ULA - z tego co wyczytałem - wystarczyło by kontrolować 3 linie /iorq /int i /m1
128k +2 UK issue 1, JS128, FDD3000 in restoration, ZAXON MGT +D, PEAR AmpY, Pear ExEar :), PEAR TI-OF-TTL+FDD35, co to tu robi??? => 2xCDTV&A500

https://soundcloud.com/silenter

https://www.youtube.com/channel/UCKZhL7Lq1zUDDnRDTJKhN4A

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #9 dnia: 2017.05.16, 16:11:25 »
I to wszystko jest bardzo fajne pod warunkiem, że wykluczysz ULA i brak podawania czegokolwiek na szynę oraz fakt, że po podłączeniu jakichś "dzikich" urządzeń może się zdarzyć, że w momencie generowania IRQ przez ULA na szynie znajduje się coś nieprzewidzianego. Albo, że twoje urządzenie pogryzie się z ULA w kwestii generowania samego IRQ.

Muszę poczytać o ULA - terra incognita poza paroma ogólnikami.

Poczytaj. Tutaj wrzuciłem OCR książki, która wyjaśnia chyba wszystko w tym temacie.

Cytuj
Sygnał przerwania jest generowany przez ULA w trakcie generowania ramki ekranu co oznacza, że na szynie nie ma "pływających atrybutów" a to oznacza, że procesor odczytuje w takiej sytuacji z szyny wartość 255 - zdecydowanie nieparzystą ;)
Jak to w ZXie - poszybkości po taniości - dobre praktyki tylko tam gdzie nie zwiększały kosztów.

No ba ;)

Tryb 1 jest do kitu w ZX bo zawsze ląduje w 0x66 czyli w ROMie. Wiem, że interfejsy podmieniają ROM i wtedy mogą przechwytywać przerwania.

Gwoli ścisłości - 0x38 albo 56 ;)

Cytuj
Dla mnie tryb 2 jest zdecydowanie najatrakcyjniejszy bo daje możliwość umiesczenia się z programem gdziekolwiek w ramie.
Swoją drogą nie widzę dla swojego interfeju zastosowań basicowych.

Problem całej tej dyskusji polega na tym, że na początku nie napisałeś co konkretnie twój interfejs ma robić ;)

Cytuj
Wyobraźmy sobie że podłączam  jakiś timer przez interfejs. Basicem ładuję mu czas. i startuję. Timer dochodzi do zera i co wywyołuje RST a procesor zaczyna wykonywać podprogram
0x66?? bez sensu. Timer powinien wywołać np. INT_0x20 a tam już powinna siedzieć procedura obsługi przerwania timera - proste jak drut. Basic nie ma tu nic do rzeczy.

Nooo... Jeśli timer to pewnie z jakąś porządną rozdzielczością i faktycznie nie dla BASICa.

Cytuj
W sofcie muszę wykryć przerwanie od ULI np. poprzez zpięcie się na INT_0xFF i zrobić jp 0x66.

W interfejsie musze co prawda zrobić kontrolę wywołania przerwania przez ULA - z tego co wyczytałem - wystarczyło by kontrolować 3 linie /iorq /int i /m1

Nie jestem pewien, czy to ci się uda - kontrolować możesz odpowiedź procesora na generowanie przerwania. Nie jestem pewien, czy INT z ULA przenosi się na szynę - wydaje mi się, że jest buforowany, ale co do tego musiałby się wypowiedzieć jakiś sprzętowiec.

Powtórzę tylko to, co powiedziałem wcześniej - moim zdaniem nie ma sensu walczyć z podkładaniem z zewnątrz wektora. Prościej jest zrobić znakowanie, że przerwanie jest twoje i stosowne potwierdzenie do tego. Ale oczywiście to twoja zabawka ;)

silenter

  • *****
  • Wiadomości: 1337
  • Miejsce pobytu:
    Warszawa/Radzymin
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #10 dnia: 2017.05.16, 16:39:41 »
Gwoli ścisłości - 0x38 albo 56 ;)
Pisałeś że Basic to tryb 1 a tryb 1 to 0x66
0x38 to tryb 0 - domyślny tryb przyjmowania przerwań maskowalnych dla Z80
128k +2 UK issue 1, JS128, FDD3000 in restoration, ZAXON MGT +D, PEAR AmpY, Pear ExEar :), PEAR TI-OF-TTL+FDD35, co to tu robi??? => 2xCDTV&A500

https://soundcloud.com/silenter

https://www.youtube.com/channel/UCKZhL7Lq1zUDDnRDTJKhN4A

silenter

  • *****
  • Wiadomości: 1337
  • Miejsce pobytu:
    Warszawa/Radzymin
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #11 dnia: 2017.05.16, 16:45:42 »
Przeglądam teraz sygnały dostępne na krawędziówce i na pozycji 16 dół mam sygnał /IORQE - co to jest za sygnał bo na cpu go nie ma.
128k +2 UK issue 1, JS128, FDD3000 in restoration, ZAXON MGT +D, PEAR AmpY, Pear ExEar :), PEAR TI-OF-TTL+FDD35, co to tu robi??? => 2xCDTV&A500

https://soundcloud.com/silenter

https://www.youtube.com/channel/UCKZhL7Lq1zUDDnRDTJKhN4A


silenter

  • *****
  • Wiadomości: 1337
  • Miejsce pobytu:
    Warszawa/Radzymin
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #13 dnia: 2017.05.16, 17:09:16 »
@nietoperz dzięki.

@matofesi - zastanówmy się nad tym aby nie korzystać z trybu 2.
czy standardowa obsługa przerwania w ZXie "zagląda" gdzieś do RAMu a jeśli tak to jak to przed czy po obsłudze klawiatury/ekranu.

Innymi słowy czy jestem w stanie się gdzieś tam zahaczyć?
128k +2 UK issue 1, JS128, FDD3000 in restoration, ZAXON MGT +D, PEAR AmpY, Pear ExEar :), PEAR TI-OF-TTL+FDD35, co to tu robi??? => 2xCDTV&A500

https://soundcloud.com/silenter

https://www.youtube.com/channel/UCKZhL7Lq1zUDDnRDTJKhN4A

nietoperz

  • ****
  • Wiadomości: 400
Odp: Interfejs generujący przerwania maskowalne w trybie 2
« Odpowiedź #14 dnia: 2017.05.16, 17:25:03 »
Znowu się wtrące bo mnie temat zaciekawił:
https://skoolkid.github.io/rom/asm/0038.html

Ja to bym ten kawałek romu (a może nawet pierwsze trzy instrukcje żeby zrobić skok bezwględny, oryginalny rom zablokować dając stan wysoki na nROMCS) podmienił własnym kodem, który jak stwierdzi, że przerwanie jest od ULA a nie od zewnętrznego urządzenia to wywołał oryginalny kod. Trochę się sprzęt skomplikuje ale co tam - jak się nie brzydzisz CPLD ;) to łatwo pójdzie. A jak przyjdzie przerwanie od ULA w trakcie obsługi twojego kodu - trudno ula miała pecha ;)