2011-08-19 212 views
5

我打算在接下來的幾個月內創建一個世嘉主系統模擬器,作爲Java中的一個業餘愛好項目(我知道這不是最好的語言,但我發現它工作起來非常舒適,並且作爲Windows和Linux的常用用戶,我認爲跨平臺應用會很棒)。我的問題是關於週期盤點;關於模擬CPU時的週期計數精度的問題

我看過了另一個Z80模擬器的源代碼,併爲其他仿真器爲好,特別是執行環令我着迷 - 當它被調用時,一個int作爲參數傳遞(假設1000作爲一個例子)。現在我知道每個操作碼都需要執行不同數量的週期,並且在執行這些操作時,週期數會從整體數字中減少。一旦剩餘的週期數爲< = 0,則執行循環結束。

我的問題是,許多這些模擬器不考慮一個事實,即要執行的最後一條指令可以推動的週期數爲負值 - 這意味着執行環之間,一個最終可能會說,執行1002個週期而不是1000個。這是否有意義?有些模擬器通過補償下一個執行循環來解決這個問題,有些則不這樣做 - 哪種方法最好?請允許我說明,我不是特別好,我的問題,在把自己跨越:

public void execute(int numOfCycles) 
{ //this is an execution loop method, called with 1000. 
    while (numOfCycles > 0) 
    { 
     instruction = readInstruction(); 
     switch (instruction) 
     { 
     case 0x40: dowhatever, then decrement numOfCycles by 5; 
     break; 
     //lets say for arguments sake this case is executed when numOfCycles is 3. 
     } 
} 

這個特殊的循環示例結束後,numOfCycles將在-2。這隻會是一個小小的不準確,但這對人們的經歷總體而言是否重要?我很感激任何人對此的洞察力。我打算在每幀之後中斷CPU,因爲這看起來很合適,所以我知道1000個週期是低的,但這只是一個例子。

非常感謝, 菲爾

回答

2

是在Arstechnica最近談論控制檯模擬一個相當有趣的文章,還鏈接到了不少模擬器,可能使相當好的研究:

Accuracy takes power: one man's 3GHz quest to build a perfect SNES emulator

相關的一點是,作者提到,而且我傾向於同意,即使定時偏差爲+/- 20%,大多數遊戲的功能也會相當正常。你提到的問題看起來可能永遠不會引入超過百分之一的時間誤差百分比,在玩最後一場比賽時這可能是不可察覺的。作者可能不認爲值得處理。

+0

感謝:-)幾天前我看到這篇文章,這是一個非常有趣的閱讀。看起來我可以忽略這個問題 - 把我的工作剪掉,但應該很有趣! :-P – PhilPotter1987

0

我想這取決於你想如何精確你的模擬器是。我不認爲它必須那麼準確。考慮x86平臺的仿真,處理器有很多種變體,每種變體都有不同的執行延遲和問題發生率。

+0

嗯,我想只要我把它綁幀率 - 說50fps的,如果我仿效PAL控制檯 - 然後這些幀之間,如果我執行如何進行多次循環,然後暫停,同時更新應該適當的屏幕。猜猜我會發現:-p感謝您的答案。 – PhilPotter1987

4
  1. 大多數仿真器/處理只是CPU時鐘模擬抽動

    這是好的遊戲等等......所以,你得到了一些定時器或什麼都和CPU運行的模擬,直到CPU模擬定時器的持續時間。然後休眠直到下一個定時器間隔發生。這很容易模擬。您可以通過您詢問的方法來減少計時錯誤。但正如這裏所說的遊戲,這通常是不必要的。

    這種方法有一個明顯的缺點這就是你的代碼只是實時的一小部分。如果定時器間隔(定時粒度)足夠大,即使在遊戲中也可以引起注意。例如,您在模擬時按下鍵盤鍵然後睡覺,則無法檢測到。 (鍵有時不工作)。您可以通過使用更小的時間粒度來彌補這一點,但這在某些平臺上非常困難。在這種情況下,定時錯誤可以在軟件生成中更「可見」聲音(至少對於那些能夠聽到它並且對我這樣的事物沒有耳聾的人)。

  2. 如果你,如果你想連接真實HW到您的仿真/模擬需要一些更復雜的

    例如,那麼你需要模擬/仿真BUS'es。還有像浮動總線爭用系統是很難添加到方法#1(這是可行的,但有很大的痛苦)。

    如果端口時序和仿真,以機器週期事情變得多容易得多突然之類的東西爭或硬件中斷,浮動BUS'es正在解決自己幾乎自己。我將ZXSpectrum Z80仿真器移植到這種時序並看到燈光。許多事情變得明顯(如Z80操作碼文檔中的錯誤,時間等)。此外,爭用從那裏變得非常簡單(幾乎每個指令類型條目幾行代碼,而不是可怕的解碼錶)。硬件仿真也很容易我添加了像FDC控制器這樣的東西AY以這種方式將仿真仿真到Z80(沒有黑客真的在他們原來的代碼上運行......甚至軟盤格式化:)),所以沒有更多的TAPE加載黑客和不工作對於像TURBO這樣的定製裝載機來說,爲了做到這一點,我創建了我的仿真/仿真模型Z80,其方式是爲每條指令使用類似微碼的東西。由於我經常更正指令集中的錯誤(因爲沒有單個100%正確的文檔,我知道即使他們中的一些人聲稱他們沒有bug並且完整)我帶着一種方式來處理如何處理它不會痛苦地重新編程模擬器。

    每條指令都由一個表中的條目表示,包含關於時序,操作數,功能的信息......整個指令集是所有指令的所有條目表。然後我爲我的指令集組成一個MySQL數據庫。並形成我找到的每個指令集的類似表格。然後痛苦地比較他們選擇/修復什麼是錯的,什麼是正確的。結果被導出到在仿真啓動時加載的單個文本文件。它聽起來很可怕,但實際上它簡化了很多事情甚至加速了仿真,因爲指令解碼現在只是訪問指針。該指令集的數據文件例如可以在這裏找到What's the proper implementation for hardware emulation

幾年前我也發表對本文(即認爲,會議已經不存在,所以服務器關閉爲好這些舊報紙幸運的是我黯然機構仍然有一個副本)所以這裏的圖像從它描述的問題羣:

CPU Scheduling

  • 一)全部throtlle沒有同步只是原始速度
  • 二)#1具有造成硬件的同步問題
  • 三)#2需要睡覺了很多非常小的粒度(可能是有問題的,慢下來)很大的差距,但這些指令非常接近執行他們的實時...
  • 紅線是主機CPU處理速度(明顯的是它上面花費更多的時間,所以應該被削減,下一條指令之前插入但它是很難正確地畫出)
  • 品紅線是仿真/模擬CPU的處理速度
  • 交替素摹green/blue顏色代表下一條指令
  • 兩個軸系是時間