Jak działają emulatory i jak są napisane? [zamknięte]

Jak działają emulatory? Kiedy widzę emulatory NES/SNES lub C64, zadziwia mnie to.

http://www.tommowalker.co.uk/snemzelda.png

Czy musisz naśladować procesor tych maszyn interpretując jego instrukcje montażu? Co jeszcze? Jak są one zazwyczaj projektowane?

Czy możesz dać jakąś radę dla kogoś zainteresowanego napisaniem emulatora (szczególnie systemu gry)?

 969
Author: Michael Myers, 2009-01-16

16 answers

Emulacja jest obszarem wieloaspektowym. Oto podstawowe pomysły i elementy funkcjonalne. Mam zamiar rozbić go na kawałki, a następnie wypełnić szczegóły poprzez edycje. Wiele rzeczy, które opiszę, będzie wymagało znajomości wewnętrznego działania procesorów.niezbędna jest wiedza na temat montażu. Jeśli jestem trochę zbyt niejasne w pewnych sprawach, proszę zadać pytania, więc mogę nadal poprawić tę odpowiedź.

Idea Podstawowa:

Emulacja działa poprzez obsługę zachowania procesor i poszczególne komponenty. Budujesz każdy pojedynczy element systemu, a następnie łączysz elementy tak, jak przewody w sprzęcie.

Emulacja procesora:

Istnieją trzy sposoby obsługi emulacji procesora:

  • interpretacja
  • dynamiczna rekompilacja
  • rekompilacja statyczna

Z tymi wszystkimi ścieżkami, masz ten sam ogólny cel: wykonać fragment kodu, aby zmodyfikować stan procesora i wejść w interakcję z "sprzęt". Stan procesora jest konglomeratem rejestrów procesora, programów obsługi przerwań itp. dla danego celu procesora. Dla 6502, masz kilka 8-bitowych liczb całkowitych reprezentujących rejestry: A, X, Y, P, i S; miałbyś też 16-bitowy PC rejestr.

Z interpretacją, zaczynasz od IP (wskaźnik instrukcji -- zwany także PC, Licznik programów) i odczytujesz instrukcję z pamięci. Twój kod przetwarza tę instrukcję i używa tej informacje do zmiany stanu procesora, jak określono przez procesor. Podstawowy problem z interpretacją polega na tym, że jest ona Bardzo powolna; za każdym razem, gdy obsługujesz daną instrukcję, musisz ją odszyfrować i wykonać wymaganą operację.

Przy dynamicznej rekompilacji, iteracja kodu jest podobna do interpretacji, ale zamiast tylko wykonywać kod opcodes, tworzysz listę operacji. Gdy dotrzesz do instrukcji branch, skompilujesz tę listę operacji do kodu maszynowego dla platformy hosta, następnie buforować ten skompilowany kod i wykonać go. Następnie po ponownym naciśnięciu na daną grupę instrukcji, wystarczy tylko wykonać kod z pamięci podręcznej. (BTW, większość ludzi nie tworzy listy instrukcji, ale kompiluje je do kodu maszynowego w locie - to utrudnia optymalizację, ale to nie wchodzi w zakres tej odpowiedzi, chyba że wystarczająco dużo osób jest zainteresowanych) {]}

Przy rekompilacji statycznej robisz to samo co w rekompilacji dynamicznej, ale podążaj za gałęziami. W końcu tworzysz fragment kodu, który reprezentuje cały kod w programie, który można następnie wykonać bez dalszej ingerencji. Byłby to świetny mechanizm, gdyby nie następujące problemy:]}

  • kod, który nie znajduje się w programie (np. skompresowany, zaszyfrowany, generowany / modyfikowany w czasie wykonywania, itp.), nie zostanie przekompilowany, więc nie uruchomi się
  • udowodniono, że znalezienie całego kodu w danym binarnym jest równoważne problem z zatrzymaniem

Te kombinacje sprawiają, że rekompilacja statyczna jest całkowicie niewykonalna w 99% przypadków. Aby uzyskać więcej informacji, Michael Steil przeprowadził świetne badania nad rekompilacją statyczną-najlepsze, jakie widziałem.

Drugą stroną emulacji procesora jest sposób interakcji ze sprzętem. To naprawdę ma dwie strony:

  • Taktowanie procesora
  • obsługa przerwań

Taktowanie procesora:

Pewne Platformy-zwłaszcza starsze konsole, takie jak NES, SNES, itp-wymagają, aby emulator miał ścisły czas, aby być całkowicie kompatybilnym. Z NES, masz PPU (pixel processing unit), który wymaga, aby procesor umieścić piksele w pamięci w precyzyjnych momentach. Jeśli używasz interpretacji, możesz łatwo policzyć cykle i emulować odpowiedni czas; przy dynamicznej/statycznej rekompilacji rzeczy są bardziej złożone.

Obsługa przerwania:

Przerwania są podstawowym mechanizm, który CPU komunikuje się ze sprzętem. Ogólnie rzecz biorąc, twoje komponenty sprzętowe powiedzą procesorowi, na czym mu zależy. Jest to dość proste - gdy twój kod rzuca dane przerwanie, patrzysz na tabelę obsługi przerwań i wywołujesz odpowiednie wywołanie zwrotne.

Emulacja sprzętu:

Istnieją dwie strony emulowania danego urządzenia sprzętowego:

  • emulowanie funkcjonalności urządzenia
  • emulowanie rzeczywistego urządzenia interfejsy

Weźmy przypadek dysku twardego. Funkcjonalność jest emulowana przez tworzenie pamięci zapasowej, procedury odczytu/zapisu/formatu itp. Ta część jest ogólnie bardzo prosta.

[[8]}rzeczywisty Interfejs urządzenia jest nieco bardziej złożony. Jest to na ogół pewna kombinacja rejestrów mapowanych w pamięci (np. części pamięci, które urządzenie obserwuje pod kątem zmian w celu sygnalizacji) i przerwań. W przypadku dysku twardego możesz mieć obszar odwzorowania pamięci, w którym umieszczasz odczyt poleceń, zapis, itd., a następnie odczyt tych danych z powrotem. Zagłębiłbym się w szczegóły, ale jest milion sposobów na to. Jeśli masz jakieś konkretne pytania tutaj, nie krępuj się zapytać, a ja dodam informacje.

Zasoby:

Myślę, że dałem całkiem dobre intro tutaj, ale jest ton dodatkowych obszarów. Jestem bardziej niż szczęśliwy, aby pomóc w razie jakichkolwiek pytań; byłem bardzo niejasne w większości z tego po prostu ze względu na ogromne złożoność.

Obowiązkowe linki do Wikipedii:

Ogólne zasoby emulacji:

  • Zophar -- tu zacząłem od emulacji, najpierw pobierałem emulatory i ostatecznie plądrowałem ich ogromne archiwa dokumentacji. Jest to absolutnie najlepszy zasób, jaki możesz mieć.
  • NGEmu -- niewiele bezpośrednich zasobów, ale ich fora są nie do pobicia.
  • RomHacking.net -- sekcja dokumenty zawiera zasoby dotyczące architektury maszyn dla popularnych konsol

Projekty emulatora do odwołania:

  • Ironbabel jest platformą emulacji dla. NET, napisaną w języku Nemerle i rekompilującą kod do C# w locie. Zastrzeżenie: to jest mój projekt, więc wybacz bezwstydną wtyczkę.
  • BSnes -- świetny emulator SNES z celem cyklu-doskonała dokładność.
  • MAME -- emulator arcade. Świetne referencje.
  • 6502asm.com -- to jest emulator JavaScript 6502 z fajnym małym forum.
  • dynarec ' d 6502asm -- to mały hack, który zrobiłem przez dzień lub dwa. Wziąłem istniejący emulator z 6502asm.com i zmienił go, aby dynamicznie przekompilować kod do JavaScript w celu ogromnego zwiększenia prędkości.

Rekompilacja procesora referencje:

  • badania nad rekompilacją statyczną przeprowadzone przez Michaela Steila (o którym mowa powyżej) zakończyły się w w tym artykule i możesz znaleźć źródło i takie tutaj.

Dodatek:

Minęło już ponad rok od złożenia tej odpowiedzi i z całą tą uwagą, jaką otrzymałem, pomyślałem, że nadszedł czas, aby zaktualizować kilka rzeczy.

Być może najbardziej ekscytującą rzeczą w emulacji jest libcpu , rozpoczęty przez wspomniany Michael Steil. Jest to biblioteka przeznaczona do obsługi dużej liczby rdzeni CPU, które wykorzystują LLVM do rekompilacji (statycznej i dynamicznej!). Ma ogromny potencjał i myślę, że zrobi wielkie rzeczy dla emulacji.

Zwróciłem również uwagę na Emu-docs , w którym znajduje się świetne repozytorium dokumentacji systemowej, które jest bardzo przydatne do celów emulacji. Nie spędziłem tam zbyt wiele czasu, ale wygląda na to, że mają dużo świetnych zasoby.

Cieszę się, że ten post był pomocny i mam nadzieję, że uda mi się wstać z dupy i skończyć książkę na ten temat do końca roku/na początku przyszłego roku.

 1127
Author: Cody Brocious,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-02 04:12:13

Niejaki Victor Moya del Barrio napisał swoją pracę na ten temat. Dużo dobrych informacji na 152 stronach. Możesz pobrać plik PDF tutaj.

Jeśli nie chcesz się zarejestrować w scribd, możesz wpisać w google tytuł PDF, "Study of the techniques for emulation programming". Istnieje kilka różnych źródeł dla pliku PDF.

 126
Author: mdm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-19 11:51:24

Emulacja może wydawać się zniechęcająca, ale w rzeczywistości jest łatwiejsza niż symulacja.

Każdy procesor ma zazwyczaj dobrze napisaną specyfikację opisującą Stany, interakcje itp.

Jeśli w ogóle nie zależało ci na wydajności, możesz łatwo emulować większość starszych procesorów za pomocą bardzo eleganckich programów obiektowych. Na przykład procesor X86 potrzebowałby czegoś do utrzymania stanu rejestrów( easy), czegoś do utrzymania stanu pamięci (easy) i coś, co pobierze każde przychodzące polecenie i zastosuje je do aktualnego stanu maszyny. Jeśli naprawdę chcesz dokładności, możesz również emulować tłumaczenia pamięci, buforowanie itp. ale to jest wykonalne.

W rzeczywistości wielu producentów mikroprocesorów i procesorów testuje programy przeciwko emulatorowi układu, a następnie przeciwko samemu układowi, co pomaga im dowiedzieć się, czy istnieją problemy w specyfikacji układu, lub w rzeczywistej implementacji układu w sprzęcie. Na przykład, jest możliwe, aby napisać specyfikację chip, który spowodowałby impas, a gdy termin występuje w sprzęcie, ważne jest, aby zobaczyć, czy może być odtworzona w specyfikacji, ponieważ wskazuje to na większy problem niż coś w implementacji chip.

Oczywiście emulatory gier wideo zazwyczaj dbają o wydajność, więc nie wykorzystują naiwnych implementacji, a także zawierają kod, który łączy się z systemem operacyjnym hosta, na przykład do korzystania z rysowania i dźwięk.

Biorąc pod uwagę bardzo powolne działanie starych gier wideo (NES/SNES itp.), emulacja jest dość łatwa na nowoczesnych systemach. W rzeczywistości, to jeszcze bardziej niesamowite, że można po prostu pobrać zestaw każdej gry SNES kiedykolwiek Lub każdej gry Atari 2600 kiedykolwiek, biorąc pod uwagę, że gdy te systemy były popularne mając wolny dostęp do każdego wkładu byłoby spełnieniem marzeń.

 43
Author: Uri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-27 16:57:10

Wiem, że to pytanie jest trochę stare, ale chciałbym coś dodać do dyskusji. Większość odpowiedzi skupia się wokół emulatorów interpretujących instrukcje maszynowe systemów, które emulują.

Istnieje jednak bardzo znany wyjątek od tego o nazwie "UltraHLE" (artykuł Wikipedii ). UltraHLE, jeden z najbardziej znanych emulatorów, jaki kiedykolwiek powstał, emulował komercyjne gry Nintendo 64 (z przyzwoitą wydajnością na komputerach domowych) w czasie, gdy był powszechnie uważane za niemożliwe do zrobienia. W rzeczywistości, Nintendo nadal produkował nowe tytuły dla Nintendo 64, kiedy powstał UltraHLE!

Po raz pierwszy widziałem artykuły o emulatorach w czasopismach drukowanych, gdzie wcześniej widziałem je tylko omawiane w sieci.

Koncepcja UltraHLE polegała na umożliwieniu niemożliwego poprzez emulowanie wywołań biblioteki C zamiast wywołań na poziomie maszynowym.

 29
Author: Daniel Allen Langdon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-08 13:30:50

Warto przyjrzeć się próbie napisania emulatora Gameboy w JavaScript.

 22
Author: Julio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-26 20:31:52

Po stworzeniu własnego emulatora mikrokomputera BBC z lat 80. (wpisz VBeeb w Google), jest wiele rzeczy, które warto wiedzieć.

    Nie naśladujesz prawdziwej rzeczy jako takiej, to byłaby replika. Zamiast tego emulujesz Stan . Dobrym przykładem jest kalkulator, prawdziwa rzecz ma przyciski, ekran, obudowę itp. Ale aby emulować Kalkulator, wystarczy emulować, czy przyciski są w górę czy w dół, które segmenty LCD są włączone, itp. Zasadniczo, zbiór liczb reprezentujące wszystkie możliwe kombinacje rzeczy, które mogą się zmienić w kalkulatorze.
  • potrzebny jest tylko interfejs emulatora, aby wyglądał i zachowywał się jak prawdziwy. Im bardziej przekonujące jest to, tym bliższa jest emulacja. To, co dzieje się za kulisami, może być czymkolwiek chcesz. Ale, dla ułatwienia pisania emulatora, istnieje mentalne mapowanie, które dzieje się między rzeczywistym systemem, tj. chipy, wyświetlacze, klawiatury, płytki drukowane i abstrakcyjny kod komputerowy.
  • To emulować system komputerowy, najłatwiej podzielić go na mniejsze kawałki i emulować te kawałki indywidualnie. Następnie ciągnąć całą partię Razem dla gotowego produktu. Podobnie jak zestaw czarnych skrzynek z wejściami i wyjściami, które pięknie nadają się do programowania obiektowego. Możesz dalej podzielić te kawałki, aby ułatwić życie.

Praktycznie rzecz biorąc, generalnie chcesz pisać dla szybkości i wierności emulacji. Dzieje się tak dlatego, że oprogramowanie na docelowy system będzie (może) działać wolniej niż oryginalny sprzęt w systemie źródłowym. Które mogą ograniczać wybór języka programowania, kompilatorów, systemu docelowego itp.
Ponadto musisz określić, co jesteś przygotowany do emulowania, na przykład nie jest to konieczne do emulowania stanu napięciowego tranzystorów w mikroprocesorze, ale prawdopodobnie jest konieczne do emulowania stanu zestawu rejestrów mikroprocesora.
Ogólnie rzecz biorąc, im mniejszy poziom szczegóły emulacji, tym większą wierność uzyskasz do oryginalnego systemu.
Wreszcie, informacje dla starszych systemów mogą być niekompletne lub nieistniejące. Tak więc zdobycie oryginalnego sprzętu jest niezbędne, a przynajmniej oddzielenie od siebie innego dobrego emulatora, który napisał ktoś inny!

 18
Author: Guillermo Phillips,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-06 08:11:05

Tak, musisz zinterpretować cały bajzel binarnego kodu maszynowego "ręcznie". Co więcej, przez większość czasu musisz również symulować jakiś egzotyczny sprzęt, który nie ma odpowiednika na docelowej maszynie.

Proste podejście polega na interpretacji instrukcji jeden po drugim. To działa dobrze, ale jest powolne. Szybszym podejściem jest rekompilacja-tłumaczenie źródłowego kodu maszynowego na docelowy kod maszynowy. Jest to bardziej skomplikowane, ponieważ większość instrukcji nie będzie mapować jeden do jednego. Zamiast będziesz musiał dokonać skomplikowanych wokół pracy, które wymagają dodatkowego kodu. Ale w końcu jest o wiele szybszy. Większość nowoczesnych emulatorów to robi.

 17
Author: Vilx-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-13 01:46:28

Podczas tworzenia emulatora interpretujesz zespół procesora, na którym pracuje system (Z80, 8080, PS CPU, itp.).

Musisz również emulować wszystkie urządzenia peryferyjne, które posiada system (wyjście wideo, kontroler).

Powinieneś zacząć pisać emulatory dla Systemów simpe, takich jak stary dobry Game Boy (które używają procesora Z80, nie mylę się) lub dla C64.

 15
Author: Baget,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-14 20:09:26

Emulatory są bardzo trudne do stworzenia, ponieważ istnieje wiele hacków (jak w nietypowych efekty), problemy z czasem itp., które trzeba symulować.

Dla przykładu zobacz http://queue.acm.org/detail.cfm?id=1755886 .

To również pokaże ci, dlaczego "potrzebujesz" procesora Wielogazowego do emulowania 1MHz.

 10
Author: Someone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-16 16:51:43

Zobacz też: Darek Mihocka ' s Emulators.com dla świetnych porad na temat optymalizacji na poziomie instrukcji dla JITs i wielu innych gadżetów na temat budowania wydajnych emulatorów.

 9
Author: Barry Bond,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-16 13:27:42

Nigdy nie robiłem nic tak fantazyjnego, aby emulować konsolę do gier, ale kiedyś brałem udział w kursie, w którym zadaniem było napisanie emulatora dla maszyny opisanej w Andrew Tanenbaums struktura organizacji komputera . To było zabawne i dało mi wiele momentów aha. Może warto podnieść tę książkę przed nurkowaniem w pisaniu prawdziwego emulatora.

 7
Author: oivvio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-21 08:32:52

Porady dotyczące emulowania prawdziwego systemu czy własnej rzeczy? Mogę powiedzieć, że emulatory działają poprzez emulację całego sprzętu. Może nie w dół do obwodu (jak ruch bitów wokół jak HW zrobi. Przeniesienie bajtu jest wynikiem końcowym, więc kopiowanie bajtu jest w porządku). Emulator są bardzo trudne do stworzenia, ponieważ istnieje wiele hacki (jak w nietypowych efektów), problemy z czasem, itp, które trzeba symulować. Jeśli jeden element (wejście) jest zły cały system może zrobić w dół lub w najlepszym przypadku mieć błąd / usterkę.

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-04 01:23:43

Emulator Shared Source Device zawiera wbudowany kod źródłowy do emulatora PocketPC / Smartphone (wymaga Visual Studio, działa w systemie Windows). Pracowałem nad wersjami V1 i V2 wersji binarnej.

Rozwiązuje wiele problemów z emulacją: - wydajne tłumaczenie adresu z wirtualnego gościa na fizyczny gościa na wirtualny host - JIT kompilacja kodu gościa - symulacja urządzeń peryferyjnych takich jak karty sieciowe, ekran dotykowy i audio - Integracja z interfejsem użytkownika, dla Klawiatury hosta i myszy - save/restore of state, for simulation of CV from low-power mode

 4
Author: Barry Bond,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-16 13:22:06

Aby dodać odpowiedź podaną przez @ Cody Brocious
W kontekście wirtualizacji, gdzie emulujesz nowy system (CPU, I/O itp.) do maszyny wirtualnej możemy zobaczyć następujące kategorie emulatorów.

Interpretacja: bochs jest przykładem interpretera , jest emulatorem komputera x86, każda instrukcja z systemu gościa tłumaczy ją w innym zestawie instrukcji (hosta ISA), aby uzyskać zamierzony efekt.Tak, jest bardzo powolny, nie buforuje niczego, więc każdy Instrukcja przechodzi przez ten sam cykl.

Dynamiczny emalator: Qemu jest dynamicznym emulatorem. Robi w locie tłumaczenie instrukcji gościa również buforuje wyniki.Najlepsze jest to, że wykonuje jak najwięcej instrukcji bezpośrednio w systemie hosta, dzięki czemu emulacja jest szybsza. Również jak wspomniał Cody, dzieli kod na bloki(1 pojedynczy przepływ wykonania).

Emulator statyczny: o ile wiem, nie ma emulatora statycznego, który mógłby być pomocny w wirtualizacji.

 1
Author: Deepthought,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-28 06:55:36

Jak bym zaczął emulację.

1.Zdobądź książki oparte na programowaniu niskiego poziomu, będziesz go potrzebował do "udawanego" systemu operacyjnego Nintendo...game boy...

2.Zdobądź książki na temat emulacji, a może Rozwoju Systemu Operacyjnego. (nie będziesz robił systemu operacyjnego, ale najbliższego.

3.spójrz na niektóre emulatory open source, szczególnie te z systemu, dla którego chcesz zrobić emulator.

4.skopiuj fragmenty bardziej złożonego kodu do IDE / compliler. To oszczędzi ci pisania długiego kodu. To jest to, co robię dla rozwoju systemu operacyjnego, używam dzielnicy Linuksa

 1
Author: 5Mixer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-01 21:31:08

Napisałem artykuł o emulowaniu układu Chip-8 w JavaScript .

Jest to świetne miejsce na początek, ponieważ system nie jest zbyt skomplikowany, ale nadal uczysz się, jak działają kody opcodes, stos, rejestry itp.

Wkrótce napiszę dłuższy poradnik dla NES.

 1
Author: alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-05 04:13:07