2017-07-25 81 views
1

我正在用C編寫我的第一個NES仿真器。目標是讓它易於理解並且循環準確(不一定必須是代碼效率),以便在正常的「硬件'的速度。在深入挖掘6502的技術參考資料時,看起來指令消耗的CPU週期不止一個 - 並且根據給定的條件(如分支)也有不同的週期。我的計劃是創建讀寫功能,並通過使用switch尋址模式對操作碼進行分組。6502每個指令的週期時間

的問題是:當我有一個多週期指令,如BRK,我需要效仿在每個週期中究竟發生了什麼:

#Method 1 

cycle - action 

1 - read BRK opcode 
2 - read padding byte (ignored) 
3 - store high byte of PC 
4 - store low byte of PC 
5 - store status flags with B flag set 
6 - low byte of target address 
7 - high byte of target address 

...或者我能不能執行在一個「週期」(一個switchcase)中的所有必需操作,並在剩餘的週期中不做任何事情?

#Method 2 

1 - read BRK opcode, 
read padding byte (ignored), 
store high byte of PC, 
store low byte of PC, 
store status flags with B flag set, 
low byte of target address, 
high byte of target address 
2 - do nothing 
3 - do nothing 
4 - do nothing 
5 - do nothing 
6 - do nothing 
7 - do nothing 

由於兩種方法都消耗了所需的7個週期,兩者之間是否沒有差異? (精度明智)

我個人認爲方法1的方式是對去解決,但是我想不出來實現它......一個適當的,簡單的方法(請幫助!)

+1

它不會有所作爲,當你只** **模擬CPU。但考慮一下外設訪問與「STA」指令相同的內存 - 當存儲單元正好改變時,這可能很重要。所以,去選項1. –

+1

至於如何,你將需要一個狀態機 –

+0

你知道任何好的C實例或來源,實現方法1嗎?我所能找到的都是非C模擬器,有些在當前級別上太複雜:( –

回答

4

你'需要?這取決於軟件。想象一下最簡單的例子:

STA ($56), Y 

......碰巧碰到一個硬件寄存器。如果您至少沒有按照正確的週期進行寫入,那麼您已經引入了時序不足。您正在寫入的寄存器將在錯誤的時間寫入。如果它像一個調色板寄存器,並且程序員正在運行柵格效果呢?然後,你剛搬到顏色發生變化的地方。你已經改變了圖形輸出。

實際上,聰明的程序員做的事情比那更聰明 - 例如,人們可以使用讀 - 修改 - 寫操作在一個確切的週期讀取硬件值,修改它,然後在其他確切的週期寫回。

所以我的答案是:

  1. 大多數軟件不寫,這樣的區別(1)和(2)會產生什麼影響;但是
  2. 有些肯定是,因爲作者很聰明;和
  3. 一些肯定是,只是因爲作者試驗,直到他們發現一個很酷的效果,無論他們是否認識到原因;和
  4. 無論如何,當您發現某些在您的模擬器上無法正常工作時,您希望花費多少時間考慮所有潛在原因的排列和組合?每一個你可以分解的是一個較少考慮。

大多數仿真器都使用你的方法(2)。通常發生的事情是他們使用90%的軟件。然後有幾個不起作用的情況,模擬器作者在這裏將特例放在這裏,這是一個特例。那些通常最終互動不佳,模擬器的餘生在支持可用軟件的不同95%組合之間搖擺,直到有人寫出更好的軟件爲止。

所以只需要使用方法(1)。它會導致一些本來不會被破壞的軟件。它還會教你更多,並且它肯定會消除特殊情況下的任何潛在動機,從而使代碼更清晰。它會稍微慢一些,但我認爲你的電腦可以處理它。

其他提示:6502只有少數尋址模式,和尋址模式完全決定了定時。 This document是您需要了解完美時機的一切。如果你想要完美的清潔度,你的開關表可以選擇一種尋址模式和一箇中央操作,然後退出,你可以在尋址模式上分支來執行主要操作。

如果你打算使用香草readwrite方法,這是一個6502智能爲每一個週期是讀或寫操作,這樣,它幾乎所有你需要說的,只是要小心的方法簽名。例如,6502有一個SYNC引腳,它允許觀察者將普通讀取與操作碼讀取進行區分。檢查NES是否將這種情況暴露給磁帶盒,因爲它經常在系統上使用,將其暴露給隱式尋呼,並且NES的主要識別特徵是有數百個尋呼方案。

編輯:次要更新:

  • 它實際上不是完全真實地說,一個6502始終讀取或寫入;它也有一個RDY輸入。如果RDY輸入有效並且6502有意讀取,它將停止,同時保持預期的讀取地址。在實踐中很少使用,因爲它不足以執行一些常見的任務,比如允許其他人佔有內存 - 6502將會寫入,無論RDY輸入如何,它的確意味着幫助單步執行 - 而且看起來不包含在NES cartridge pinout中,您無需爲該機器實施它。
  • 每個相同的引腳,同步信號也似乎沒有暴露在該系統的墨盒。
+0

好一個湯米。你說我確實太累了,無法打字。很長一段時間,我想編寫一個微代碼6502. @ H.J Jang:天真的方式是交換機(操作碼)中每個操作碼的開關(循環)語句。另一種方法是寫一個微碼錶(你的方法#1)。正如Tommy所說,除了實際的操作碼操作外,每種尋址模式都有相同的順序。 –

+0

@NickWestgate我現在的6502仿真是微碼! Microcode發明的時候雖然沒有事先做好準備,但並不理想。我已經對Z80進行了微碼編碼,而且我的系統更加系統化。自90年代以來,我的6502模擬的演變:(1)函數指針表,不循環準確; (2)一個大的開關語句,接通指令,週期準確但只能運行一整個指令,所以必須是時間主站; (3)一個大的開關語句,接通指令,分離線程,必要時阻塞運行任意數量的週期; (4)微碼。 – Tommy

+0

這個答案提供了一個很好的解釋,我試圖在我的評論中表達出來,+1從我:) –

相關問題