Autor Wątek: Kurs programowania w asm (dla ZX na początek)...  (Przeczytany 48015 razy)

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #30 dnia: 2019.06.06, 17:31:01 »
Synchronizację co ramkę można też uzyskać przez:

halt ; czekaj na kolejne przerwanie

Taaa...
Wciskasz jakiś klawisz i już po synchronizacji.
Do tego dziwne zakłócenia tej synchronizacji rytmicznie co kilka sekund.
Trzeba pamiętać, że przerwanie INT to standardowo skok do procedury w ROM, a czas jej wykonania zależy np. od wciśnięcia klawiszy, a co 256 cykli (ok. 4,3 s) nieco więcej taktów zawiera aktualizacja 24-bitowego licznika ramki.
Kod umieszczony po HALT będzie wznowiony dopiero po zakończeniu procedury przerwania w ROM-ie.

tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #31 dnia: 2019.06.06, 17:49:15 »
To znaczy synchronizacja przez HALT jest ale nie najlepsza.

To może uda się wytłumaczyć, jakoś prostymi słowami jak to zrobić.
W końcu nie trzeba wszystko rozumieć do końca aby używać.

Teraz to mamy taką epokę że mamy raczej małe pojęcie jak co działa, a używamy.
Od telefony do samochodu.
Skończyła się epoka ludzi omnibusów, którzy byli w stanie wiedzieć wszystko o wszystkim.
ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235

Phonex

  • *****
  • Wiadomości: 1260
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #32 dnia: 2019.06.06, 18:01:17 »
Trzeba pamiętać, że przerwanie INT to standardowo skok do procedury w ROM, a czas jej wykonania zależy np. od wciśnięcia klawiszy, a co 256 cykli (ok. 4,3 s) nieco więcej taktów zawiera aktualizacja 24-bitowego licznika ramki.
Kod umieszczony po HALT będzie wznowiony dopiero po zakończeniu procedury przerwania w ROM-ie.

Nie co 256, tylko co 65536 przerwań - czyli 21 i coś MINUT :P
A naciskanie klawisza czasem nie ma znaczenia, jeśli np. po naciśnięciu program i tak przechodzi dalej.
Mój programik na Wyzwanie #4 w drugiej części synchronizuje się przez HALT w trybie IM1 i jest malinowo :)
https://www.speccy.pl/forum/index.php?topic=3339.msg51420#msg51420

EDIT: Właśnie sprawdziłem co się dzieje przy naciskaniu klawisza jak nie powoduje to wyjścia z animacji (usunąłem sprawdzanie klawisza). Otóż nic się nie dzieje - dalej chodzi płynnie 8)
« Ostatnia zmiana: 2019.06.06, 18:21:09 wysłana przez Phonex »

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #33 dnia: 2019.06.06, 18:19:03 »
Moim zdaniem najlepiej zrobić własną obsługę przerwań INT.
Po pierwsze, potrzebna jest tablica wektorów dla trybu drugiego (IM 2). Potrzebujemy 2x256=512 bajtów.
O ile mnie pamięć nie myli, działa to tak, że starszy bajt tej tablicy wektorów ładujemy do rejestru I, a młodszy bajt jest odczytywany z szyny danych w momencie przyjęcia przerwania. Jako że Spectrum nie ma żadnych urządzeń wystawiających wektory w ten sposób, młodszy bajt może być z zakresu 0..255, stąd potrzeba takiej tablicy.
Adres pobrany z tablicy (dwa bajty) jest adresem skoku do procedury obsługi przerwań.

Uwaga, żeby procedura była synchroniczna z ramką, nasz kod obsługi przerwania powinien być w "górnej" pamięci (uncontended).

Załóżmy, że nasza procedura zaczyna się od adresu 32768, czyli #8000. Budujemy naszą tablicę wektorów przerwań, dajmy na to, od adresu 49152 (#C000). Poczynając od tego adresu, wypełniamy 512 bajtów wartościami #00 i #80 (naprzemiennie), czyli mamy 256 razy słowo 16-bitowe #8000.

Kod inicjujący obsługę przerwań powinien blokować przerwania (DI), ładować do rejestru I starszy bajt tablicy (#C0), włączać tryb IM 2 i odblokowywać przerwania (EI).

Nasz kod obsługi przerwań pod adresem #8000 powinien (podobno) blokować przerwania rozkazem DI (choć podobno przyjęcie przerwania robi to automatycznie). Dalej mamy kod synchroniczny z ramką, bez skoków/pętli warunkowych. Na koniec skaczemy do ROM pod adres 56 (#38), by odczytać klawiaturę, zaktualizować licznik ramek itp.

Jak ktoś lubi cwaniaczyć, to jako tablicę wektorów może wykorzystać obszar ROM wypełniony wartościami #FF (255) od adresu #386E do #3CFF. Potrzebujemy 512 bajtów, a w podanym zakresie jest ponad kilobajt. Początek tablicy będzie oczywiście pod adresem #nn00, czyli #3900, #3A00, #3B00 lub #3C00. Obsługa przerwania będzie wtedy pod adresem #FFFF, gdzie należy umieścić wartość 24 (#18), czyli kod operacji JR. Następny odczytany bajt, czy adres skoku względnego, będzie pobrany spod adresu #0000 (pamięć ROM), czyli będzie to #F3 (kod instrukcji DI). Instrukcja JR #F3 oznacza skok o -13, czyli od bieżącej wartości licznika PC (#0001) odejmujemy 13 i lądujemy pod adresem #FFF4 (65524). Pod tym adresem robimy skok do naszego kodu obsługi przerwań, np. JP #8000.

EDIT: To co pokreślone, jest nie do końca prawdą zgodnie z tym, co napisał potem Phonex :)
« Ostatnia zmiana: 2019.06.06, 19:28:39 wysłana przez trojacek »

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #34 dnia: 2019.06.06, 18:22:02 »
Nie co 256, tylko co 65536 przerwań - czyli 21 i coś MINUT :P

Zajrzałem do ROM-u, i faktycznie - inkrementacja jest na słowie 16-bitowym.

Cytuj
A naciskanie klawisza czasem nie ma znaczenia, jeśli np. po naciśnięciu program i tak przechodzi dalej.
Mój programik na Wyzwanie #4 w drugiej części synchronizuje się przez HALT w trybie IM1 i jest malinowo :)

"Obsuw" o 4 takty (czyli i tak minimalistycznie) oznacza przeskok o 8 pikseli.
Może akurat Twój efekt tak ma, że nie widać efektu.
Do prostych rzeczy faktycznie styknie, nie trzeba się babrać w IM 2.
« Ostatnia zmiana: 2019.06.06, 18:40:23 wysłana przez trojacek »

Phonex

  • *****
  • Wiadomości: 1260
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #35 dnia: 2019.06.06, 18:46:05 »
Moim zdaniem najlepiej zrobić własną obsługę przerwań INT.

No pewnie że najlepiej, mówię tylko że nie zawsze trzeba.

A co do trybu IM2:
Skoro młodszy bajt może być z zakresu 0..255, to tablica ma mieć 256+1 bajtów. Dlaczego 257? Bo dla każdej wartości młodszego bajta adresu pobierane są dwa bajty jako adres procedury obsługi!
A ponieważ może przybrać każdą z tych wartości, to nie można jej wypełniać dwoma wartościami, tylko jedną. W efekcie oba bajty adresu muszą być takie same! Np. wstawiamy #80. Zostanie w każdej sytuacji odczytany adres #8080, a pod adresem #8080 wstawiamy skok gdzie nam się podoba, np. JP #8100.

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #36 dnia: 2019.06.06, 18:49:09 »
A co do trybu IM2:
Skoro młodszy bajt może być z zakresu 0..255, to tablica ma mieć 256+1 bajtów. Dlaczego 257? Bo dla każdej wartości młodszego bajta adresu pobierane są dwa bajty jako adres procedury obsługi!

No, sporo jednak zapomniałem przez te >20 lat niedotykania asemblera :D
Coś mi chodziło po głowie, że ta tablica wektorów jest lekko nierówna, ale nic na ten temat nie znalazłem.
Niemniej rozwiązanie z tablicą #FF jest OK :D

Phonex

  • *****
  • Wiadomości: 1260
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #37 dnia: 2019.06.06, 19:26:10 »
Jest OK, sam tak kiedyś zrobiłem, ale ktoś pisał że nie zawsze...
W Spectrum 128 nie ma tam samych #FF-ów. A program działa mimo tego poprawnie (np. mój Start s12).

OK, zajrzałem do ROMU ZX 128, okazuje się że cwaniaki zostawili dwa #FF-y pod adresami #39FF, #3AFF i #3BFF!!!
(#3CFF odpada, bo nawet w ZX 48K jest tam tylko jeden #FF, dalej są już fonty).
Będzie działać jak odczyta z szyny #FF, czyli bez podłączonych interfejsów. Z interfejsem może się wywalić.
Kolejna z 11 tajemnic wyjaśniona :D

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #38 dnia: 2019.06.06, 19:32:29 »
Szanse są niewielkie, bo żeby się wywaliło, trzeba by mieć interfejs z jakimś układem z rodziny Z80 (CTC, PIO, DMA, SIO, KIO, CIO). Rodzina intelowska (8xxx) raczej nie potrafi wystawiać po przerwaniu wektora na szynę danych. Choć trzeba by to sprawdzić :D

steev

  • *****
  • Wiadomości: 1362
  • Miejsce pobytu:
    inode 42
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #39 dnia: 2019.06.06, 19:35:00 »
Szanse są niewielkie, bo żeby się wywaliło, trzeba by mieć interfejs z jakimś układem z rodziny Z80 (CTC, PIO, DMA, SIO, KIO, CIO). Rodzina intelowska (8xxx) raczej nie potrafi wystawiać po przerwaniu wektora na szynę danych. Choć trzeba by to sprawdzić :D
A floating bus nie może czasem wejść tu w paradę?
Muszę się chyba napić, bo na trzeźwo głupoty gadam...
Machines should work. People should think.

Phonex

  • *****
  • Wiadomości: 1260
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #40 dnia: 2019.06.06, 19:42:34 »
A to co "akurat już jest" na szynie danych w momencie przerwania nie ma znaczenia?
Np. odczyt joysticka?

Czy ja też głupoty gadam? Chyba tak, bo naciskanie klawiszy nie wywala, a to też odczyt z portu...

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #41 dnia: 2019.06.06, 19:48:32 »
@steev, zadałeś bardzo dobre pytanie, co zatem spowodowało, że je wykreśliłeś?
@Phonex, chyba znam odpowiedź, to się powymądrzam ;)

Otóż cykl potwierdzenia przyjęcia przerwania INT powoduje wystawienie przez CPU aktywnych linii /IORQ oraz /M1 (które w żadnej innej sytuacji nie są aktywne razem). W odpowiedzi na ten stan urządzenie zewnętrzne wystawia swój wektor.
I otóż: ani joystick, ani floating bus, ani żaden inny port I/O żadnego interfejsu nie powinien wystawiać niczego innego, ponieważ linia /RD jest w stanie wysokim.

steev

  • *****
  • Wiadomości: 1362
  • Miejsce pobytu:
    inode 42
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #42 dnia: 2019.06.06, 19:57:48 »
@steev, zadałeś bardzo dobre pytanie, co zatem spowodowało, że je wykreśliłeś?
Bo IIRC INT jest generowany wewnątrz impulsu synchronizacji pionowej.
ULA wtedy nie generuje obrazu.
Machines should work. People should think.

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #43 dnia: 2019.06.06, 20:04:27 »
Ale INT może też przyjść z zewnątrz komputera...

steev

  • *****
  • Wiadomości: 1362
  • Miejsce pobytu:
    inode 42
Odp: Kurs programowania w asm (dla ZX na początek)...
« Odpowiedź #44 dnia: 2019.06.06, 20:09:46 »
Tak.
Ale nie kojarzę żadnego takiego interfejsu, poza slo-mo.
(choć nie znam na pamięć schematów wszystkich stacji dysków, może któraś z nich też...  :) )
Machines should work. People should think.