2

Ok.I可以找到模擬設計爲簡單架構(編輯:絕對不一樣的x86)。

例如使用int作爲程序計數器,使用byte array作爲記憶和等等。

但是,我怎樣才能模擬圖形卡(最簡單的圖形卡可想象)的功能?

類似於使用array來表示每個像素並逐一「繪製」每個像素。
但是何時繪製與CPU同步或異步?誰在該陣列中存儲graphic data?是否有存儲像素和繪製像素的指令?
模擬一個簡單的圖形卡

請考慮所有問號('?')並不意味着「你問了很多問題」,而是解釋了問題本身 - 如何模擬顯卡?

編輯:LINK到的基本實現設計CPU +內存模擬

+1

你想開始編寫一個驅動程序,提供一個已知的API,可能是OpenGL。在這之後,你可以做任何你想做的事(並且有OGL軟件實現可以參考)。 – ssube

+0

簡單地說,我要求的是數據結構/ s來表示圖形卡和算法來獲得功能。 – Dinushan

+1

這是功課嗎? :) –

回答

2

圖形卡通常攜帶許多KB的或存儲器的MB,其存儲各個像素被然後在屏幕上顯示的顏色。該卡片每秒掃描一次該存儲器多次,將像素顏色的數字表示轉換爲顯示器理解和可視化的視頻信號(模擬或數字)。

CPU可以訪問這個存儲器,每當它改變它時,卡片最終將新的顏色數據轉換成適當的視頻信號,並且顯示器顯示更新的圖片。該卡異步執行所有處理,不需要CPU提供太多幫助。從CPU的角度來看,它很像是將新的像素顏色寫入顯卡的內存中對應像素座標的位置,然後忘記它。實際情況可能稍微複雜一些(由於較差的同步僞像,如tearing,snow等),但這是它的要點。

當您模擬圖形卡時,需要以某種方式鏡像模擬卡在物理圖形卡內存中的內存。如果在操作系統中,您可以直接訪問物理圖形卡的內存,這是一件容易的事。簡單地實現寫你的仿真計算機這樣的記憶:

void MemoryWrite(unsigned long Address, unsigned char Value) 
{ 
    if ((Address >= SimulatedCardVideoMemoryStart) && 
     (Address - SimulatedCardVideoMemoryStart < SimulatedCardVideoMemorySize)) 
    { 
    PhysicalCard[Address - SimulatedCardVideoMemoryStart] = Value; 
    } 

    EmulatedComputerMemory[Address] = Value; 
} 

以上,當然,假設模擬卡具有完全相同的分辨率(比如1024×768)和像素表現(比如,3個字節每像素,第一個字節爲紅色,第二個爲綠色,第三個爲藍色)作爲物理卡。在現實生活中,事情可能會稍微複雜一些,但這也是一般想法。

如果您的代碼可以通過PC BIOS啓動您的代碼並將其限制爲僅使用BIOS服務功能(中斷)和直接硬件訪問,則您可以直接在MSDOS中或在沒有任何OS的裸機上訪問物理卡的內存對於所有其他PC設備。

順便說一句,它可能會很容易實現你的模擬器作爲DOS程序,並直接運行它在Windows XP(Vista和7有非常有限的32位版本的DOS應用程序的支持,並沒有在64位版本;但是,您可能會安裝XP Mode,這是XP中虛擬機中的XP),或者更好,但類似於DOSBox,似乎可用於多個操作系統。

如果你將這個東西作爲一個Windows程序來實現,你將不得不使用GDIDirectX來在屏幕上繪製東西。除非我錯了,否則這兩個選項都不能讓您直接訪問物理卡的內存,以便自動顯示其中的更改。

如果有很多渲染,使用GDI或DirectX在屏幕上繪製單個像素可能會很昂貴。每當其中一個被改變時,重新繪製所有模擬卡的像素就會導致相同的性能問題。最好的解決方案可能是每秒更新一次屏幕25-50次,並且只更新自上次重繪以來更改過的部分。將模擬卡的緩衝區細分爲代表64×64像素的矩形區域的較小緩衝區,每當仿真器寫入它們時將這些緩衝區標記爲「髒」,並在屏幕上繪製時標記爲「乾淨」。你可以設置一個週期性的定時器驅動屏幕重繪,並在一個單獨的線程中完成。你應該可以在Linux中做類似的事情,但我對那裏的圖形編程知之甚少。

+0

感謝您的優秀解釋 – Dinushan