Emulatorkonstruktion Schema Inledning Andra metoder Mina metoder Demonstration av min C64-emulator Sammanfattning och frågor
Inledning Vad är en emulator? Mikrodator Commodore 64 Emulator, CCS64 Implementerad för PC, UNIX Konkurrens sedan 1987 Högst kompatibilitet
Mikrodator Processor (CPU) Minne Adress och data-buss MMU (Memory management unit) DMA (Dynamic memory access) I/O-portar samt räknare Grafikprocessor Ljudprocessor Externa enheter
Commodore 64 Förenklad modell över intern kommunikation
Commodore 64 Förenklad modell över processorn (MOS6510)
Andra metoder Kompilerande Byggda på en förenklad/felaktig modell Maskinberoende Assembler Ej objektorienterad/modulariserad uppbyggnad Ineffektiva lösningar Lägre kompatibilitet
Min modell Korrekt modell Tyngdpunkt på korrekt exekverande av program Virtuell värld Maskinoberoende kärna med generella gränssnitt Objektorienterad/modulariserad design Händelser (Events) Uppbyggd kring processorn Emulering i flera steg
Processor Register => C++ Variabler Följer ursprunglig mikrokod Synkroniserad med klockcykler while(!undantag) { switch(...) { case 0x00:... break;... case 0xff:... break; } if(!avbrott) {... }...
Minne och MMU Minne => Fält (Array) av heltal Tabell över adresserbart minne Indelad i RAM, ROM, I/O case 0xa9:/* LDA Immediate a = LÄSFRÅNMINNE(pc++); zn = a; break; LÄSFRÅNMINNE: reg = MinnesTabell[adress]; if(reg == 0) return Ram[adress]; elseif(reg == 1) return Rom[adress]; else return LäsIO(reg,adress);
Händelser Uppdatering av andra enheter Sorterad lista med trädstruktur Kontroll vid varje tidsenhet (minnesåtkomst) maskincykel++; if(maskincykel == händelsecykel) { maskincykel = KollaHändelse(maskincykel); händelsecykel = NästaHändelse(händelsecykel); } KOLLAHÄNDELSE: switch(grundtyp) { case 1:/* Exempelvis att någon enhet gör DMA åtkomst */ break; case 2:/* Grafikprocessor */... case 3:... }
Grafik och ljud Uppdelat i arbete som berör exekveringen eller inte Förändringar sparas i buffert Genererar data i ett separat arbetssteg
Implementation Exekvering i steg motsvarande en viss tid (skärmsvep) Konverterar generell data till/från emulatorkärnan till/från plattformspecifik implementation while(1) { HandleInput(); ExecuteCPU(); GenerateSound(); while(!NextTimeStep()) { GenerateGFX()... }... }
Sammanfattning Kunskap i minsta detalj Virtuell maskin Händelsestyrd Mycket hög kompatibilitet Enkel att implementera på olika plattformar Ej extern synkronisering Ej lämplig för datorer med flera exekverande processorer