Autor Wątek: Emulacja a przerwanie zegarowe  (Przeczytany 6694 razy)

Frodo

  • *
  • Wiadomości: 18
Emulacja a przerwanie zegarowe
« dnia: 2015.12.22, 09:59:51 »
O ile dobrze zrozumiałem, jedyne asynchroniczne przerwanie ZX Spectrum to przerwanie zegarowe 50 /s, a klawiatura odpytywana jest w tym przerwaniu przez In?
Jak jest zrobiona w emulatorach obsługa tego przerwania, w pececie są tylko takie możliwości jak sleep(), i w Windows mamy przerwania częstotliwości 64 Hz a W Linuxie 100 Hz, chyba że w najnowszych Windows zwiększono częstotliwość. Jak symulować by mieć wrażenie że przerwania są 50 /s?

trojacek

  • *****
  • Wiadomości: 6846
  • Miejsce pobytu:
    Warszawa
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #1 dnia: 2015.12.22, 10:07:40 »
Na PC masz programowalne timery:
https://en.wikipedia.org/wiki/Programmable_interval_timer

Kiedyś życie było prostsze - wpisywało się do rejestru timera dzielnik częstotliwości i tyle. Oczywiście nie należy używać timera systemowego (0).
Od Windows XP w górę nie masz bezpośredniego dostępu do zasobów I/O, ale każdy język programowania jakoś to rekompensuje, bądź też trzeba poszukać odpowiedniego DLL-a dla Windows, takiego, który daje dostęp do I/O.

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4540
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #2 dnia: 2015.12.22, 10:09:54 »
ULA generuje przerwanie do 1/50s, czyli wtedy, kiedy następuje wyświetlenie obrazu.

To, jak ono jest obsługiwane przez procesor, zależy od ustawień przerwań.

Jeżeli chodzi o odczyt stanu klawiatury to  może ono być zrobione w dowolnym momencie, a sama klawiatura nie generuje przerwań.

Co to tego jak zaimplementować przerwania co 50Hz w emulatorze i aby to jeszcze dobrze wyglądało, nie powiem. Próbują to zrobić od lat, z różnym skutkiem, a pogodzenie 50Hz z 60Hz nie jest proste.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #3 dnia: 2015.12.22, 10:14:13 »
Poza wszystkim innym w wypadku emulacji przerwanie musi wypadać niekoniecznie 50 razy na sekundę. Istotniejsze jest, żeby było co odpowiednią liczbę cykli procesora, wtedy emulacja będzie działała poprawnie. Do tego oczywiście musi dojść synchronizacja emulowanego ekranu z procesorem (tak, żeby m.in. poprawnie działało memory contention ale też potencjalny tearing itp.).

Jak rozumiem większość emulatorów asynchroniczność przerwań symuluje właśnie w taki sposób, że generuje przerwania zgodnie z emulacją przebiegów czasowych procesora a nie 50 razy na sekundę. Takie podejście pozwala wtedy na przykład ustawić prędkość emulacji na kilkaset procent i oglądać poprawne działanie programu w odpowiednim przyspieszeniu.


Frodo

  • *
  • Wiadomości: 18
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #4 dnia: 2015.12.22, 10:42:41 »
Czyli biorę instrukcje, interpretuję je, zliczam takty: 3.5 MHz, na 50 to 70 tys taktów czyli 10 tys instrukcji. Wykonuję synchronicznie procedurę gdy licznik taktów osiągnie pewną wielkość. To rzeczywiście upraszcza sprawę. Interpretacja jest wolna, ale korzysta się z tego że pecet jest o wiele szybszy i kłopot może być z tym że w grach emulator będzie zbyt szybki. Ale gdybym chciał uzyskać pełną prędkość tłumacząc kod Z80 na instrukcje Pentium , które bym wykonywał?

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #5 dnia: 2015.12.22, 10:54:52 »
Ja to widzę tak:

- kiedyś  w latach 90-tych nikt nawet nie próbował robić w emulatorach jakiejś idealnej synchornizacji z prawdziwym Zx Spectrum. Po prostu pisał człowiek emulator tak żeby chodził najszybciej jak się da a i tak na jakimś PC 286 chodziło to wolniej niż na prawdziwym Spectrum.

Obecnie mamy sprzęt który pozwala uruchomić emulatory  z prędkością np. 20 x oryginalna prędkość Spectrum a pewnie i 100 x  jakby ktoś chciał. Przypuszczam że nikt nie liczy tutaj milisekund tylko takty procesora Z80. Między przerwaniami jest dokładnie ileś tam taktów i jak taka wielkość się odliczy to generowane jest przerwanie - wywoływany jest kod jego obsługi i jakaś metoda RysujEkran()

Natomiast czy ekran zostanie rzeczywiście wyświetlony na monitorze to już inna sprawa i za to chyba już raczej odpowiada jakiś sterownik karty graficznej a nie emulator. Większość emulatorów chodzi z częstotliwością 50 Hz natomiast monitor ma odświeżanie 60 Hz i jakoś tam się to rozjeżdza - zgadywałbym że niektóre odświeżenia ekranu są wyświetlane po 2 razy. Niektórzy nawet twierdzą że to widzą.

EDIT: Zauważyłem że napisałem właściwe to samo co inni ale niech już zostanie :)

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #6 dnia: 2015.12.22, 11:01:35 »
Cytuj
Czyli biorę instrukcje, interpretuję je, zliczam takty: 3.5 MHz, na 50 to 70 tys taktów czyli 10 tys instrukcji. Wykonuję synchronicznie procedurę gdy licznik taktów osiągnie pewną wielkość

Bardzo z grubsza tak. W praktyce jest to bardziej skomplikowane. Tutaj możesz sobie trochę poczytać:

http://www.worldofspectrum.org/faq/reference/48kreference.htm

Cytuj
Interpretacja jest wolna, ale korzysta się z tego że pecet jest o wiele szybszy i kłopot może być z tym że w grach emulator będzie zbyt szybk
i

Nie ma kłopotu bo wstawiasz odpowiednio wyliczone opóźnienie

Cytuj
Ale gdybym chciał uzyskać pełną prędkość tłumacząc kod Z80 na instrukcje Pentium , które bym wykonywał?

Yyy, że niby chciałbyś pisać emulator w asemblerze PC??? To już raczej nie te czasy :)




Frodo

  • *
  • Wiadomości: 18
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #7 dnia: 2015.12.22, 11:38:43 »
Nie, napisany w C++, ale jedna możliwość to korzysta z instrukcji jako danych, które interpretuje, a druga - tworzony jest proces debugowany ale to chyba za trudne.
A jak zachowa się procesor, gdy wyłączymy przerwania. chyba nadal odświeża ekran z pamięci, a gdy włączymy - czeka na następne przerwanie czy od razu po włączeniu wykonuje przerwanie? Chyba czeka.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #8 dnia: 2015.12.22, 11:50:44 »
A jak zachowa się procesor, gdy wyłączymy przerwania. chyba nadal odświeża ekran z pamięci, a gdy włączymy - czeka na następne przerwanie czy od razu po włączeniu wykonuje przerwanie? Chyba czeka.

Oczywiście, że czeka. Przerwanie maskowalne w Spectrum jest jedno i jeśli jego obsługa jest wyłączona to procesor po prostu ignoruje sygnał generowany przez ULA a że przerwanie nie wymaga jakiegoś potwierdzenia itp. to jeśli akurat było wyłączone to po prostu zostanie przeskoczone.

Druga kwestia, że jak będziesz liczył czas na całą ramkę i synchronizował całą emulację do przerwania to taki emulator możesz sobie od razu odpuścić ;)
Problem polega na tym, że sygnał zegarowy dla procesora w Spectrum generuje ULA i jeśli jest taka potrzeba to zegar jest po prostu zatrzymywany na od jednego do nawet 6 taktów, co powoduje, że nie da się wprost policzyć ile cykli/taktów wykona procesor w jednej ramce. Jeśli w ogóle nie dotyka dolnej pamięci to wtedy można sobie policzyć sumę taktów i tej liczby używać do jakiejś synchronizacji. Jeśli jednak próbuje się dostać do tej pamięci w tym samym czasie co ULA to zaczyna zwalniać zależnie od tego w którym momencie dostępu do pamięci ULA nastąpiła próba dostępu do pamięci przez procesor. Do tego oczywiście ULA generuje obraz w trakcie wykonywania kodu przez procesor i moment pobierania danych z pamięci trzeba zsynchronizować z momentem zapisu tak aby emulowany "raster" wyświetlał to, co faktycznie w tym momencie znajduje się w pamięci.

Bez uwzględnienia tych efektów będziesz miał emulator, który będzie za szybki a do tego nie będzie poprawnie pokazywał bardziej zaawansowanych efektów graficznych.

Frodo

  • *
  • Wiadomości: 18
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #9 dnia: 2015.12.22, 14:17:40 »
moment pobierania danych z pamięci trzeba zsynchronizować z momentem zapisu tak aby emulowany "raster" wyświetlał to, co faktycznie w tym momencie znajduje się w pamięci.

Brzmi groźnie, jak to można uzyskać?

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #10 dnia: 2015.12.22, 14:43:54 »
Software'owo? Licząc cykle pracy procesora i synchronizując z cyklami pracy ULA ;)
Przebiegi rastra (czyli sposób wyświetlania ekranu przez ULA) są do znalezienia choćby u nas na forum i pokazują ile cykli procesora zajmuje każdy z elementów ekranu a z tego wprost można sobie wyciągnąć informację w którym punkcie na ekranie które dane są pobierane. Pewnie da się na to zrobić jakieś funkcje przeliczające tak, żeby odpowiednio generować wirtualny zegar dla procesora i wszystko ze sobą synchronizować.

Jeśli faktycznie chcesz zrobić porządny emulator Spectrum, to sugeruję na początek poczytać o tym, co dokładnie tam siedzi w środku. Świetnym materiałem jest to: http://www.amazon.co.uk/ZX-Spectrum-Ula-Microcomputer/dp/0956507107
W książce są rozrysowane wszystkie bloki funkcjonalne ULA z dokładnym wyjaśnieniem, wykresami przebiegów pracy itp. Poza wszystkim innym jest to świetna lektura, a do pisania emulatora moim zdaniem nieodzowna. Choć można poszukać materiałów w innych miejscach - timingi są objaśniane w wielu miejscach mniej lub bardziej zrozumiale. Można też podejrzeć w źródłach u "konkurencji", ale to trochę niesportowo ;)

Szczerze powiedziawszy ja bym się nie rzucił na pisanie emulatora właśnie głównie dlatego, że wiem jak to wszystko działa i wiem na ile skomplikowanym projektem jest zgranie tego wszystkiego do kupy tak, żeby działało jak należy :) A średnich emulatorów jest do ściągnięcia od metra i troszeczkę ;)

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Emulacja a przerwanie zegarowe
« Odpowiedź #11 dnia: 2015.12.22, 14:46:20 »
Jeśli brzmi groźnie to na razie to olej.

W wersji 1.0 możesz spokojnie zrobić emulator bez jakiejkolwiek synchronizacji generowania obrazu z przebiegiem kodu. Po prostu 50 razu na sekundę na początku ramki zrzucaj w jednym rzucie pamięć graficzną na ekran i już.

Multocolory  i inne sztuczki nie będą działać ale w 90% gier da się grać