2016年9月17日 星期六

Apr8086 雛形Demo

https://dl.dropboxusercontent.com/u/61164954/project/Apr8086/index.htm


趁著連假這幾天趕了一下進度,開始檢查和修正之前寫好的8086 cpu code指令模擬的bug,利用fakePC這個project加以修改,匯出執行每一個步驟的各暫存器的log,用來檢查自己的專案正確性,持續修正到將BIOS畫面輸出,由於尚未時做控制周邊IO,目前會讀到IO的回傳部分是依賴fakePC記錄輸出(建立步驟與io回應的關係),記錄了步驟從從1~1100000 其中會回傳io read的部分,順利到達系統記憶體checking階段,然後就暫時先停止運作,等待日後更完整實作.

目前撰寫起來,雖然8086 cpu模擬也還稱不上困難(相對於arm解碼, 8086已經算是很好處理了),但這顆16bits的cpu相較前身8008來說整體運作已經付雜很多,主要是x86的節區運作觀念,幾個節區暫存器怎樣的狀況下使用哪個,又記憶址分成 effective address (EA) 與 physical address (PA),每種狀況下換算用的方式又盡不同,以及所謂的prefix指令,最後就是雜七雜八的定址法,跟8bits cpu時代相比完全不可一概而喻了,但CPU要用軟體模擬只要規則搞懂,flag沒搞錯,基本上也就是規格書怎麼描述,你就依樣畫葫就是,所以錯得再怎麼多,只要有耐性,跟別人的的steps log比對,看看問題出在哪還節哪個指令,慢慢修正下去,都還可以處理.

比較麻煩的,對於像我這種悟性比較不足.硬體接觸經驗又相對不足的人來說,幾個周邊裝置io的了解與模擬,我認為才是後面階段的大重點.

由於這並非是我我的工作,只是我的興趣與休閒,因此之後進度也沒很刻意要求,一切隨意.

2016年8月17日 星期三

8086 指令集模擬完成後

單只有CPU不能稱上是一部電腦,若只是把指令集模擬完成,還是沒有任何作用,於是開始進入相關電腦周邊控制模擬的階段,簡單來說cpu可以透過 IN OUT 兩個指令對 IO port 做溝通,在8086中這個 IO port 很相似於一個獨立的記憶體介面位址(只是讀寫的是裝置) , port 位址從 0x0 ~ 0xffff  (不確定 8086之後是不是也是這樣) , 鍵盤.滑鼠.軟碟片.顯示卡...有的沒的基本周邊都要透過 IO port去溝通存取控制, 而且各自的控制器都有各自的規則特性 , 需要去了解 , 完成了cpu的指令模擬真的才完成整個專案的一小塊部分,所以還有一段路得走.

列出參考  http://wiki.osdev.org/I/O_Ports

每一個裝置控制器要了解又得花不少功夫(至少對我這種平凡的人來說)......

其實後來看別人的project sources做法,有些似乎沒有真正完整實做這些周邊的功能特性(控制器規則等等),只是把DOS跟BIOS用到的中斷服務最後結果給做出來,簡單來這算是一種取巧的做法,這種作法有利有弊,優點大概就是程式較為簡略些,我只要管呼叫這個中斷要得到什麼正確的結果,更底層 IN OUT對周邊的動作控制細節不用真的處理到,速度理論上也比較快.缺點大概是相容性有限,如果是別的作業系統中斷功能定義跟DOS不同,當然就有問題 ,這種差異大概就像是 Dosbox 和  Bochs 兩種實做的差異 , dosbox官翻網站所言

https://www.dosbox.com/links.php

 Bochs emulates a full x86 based pc. Unlike DOSBox that tries to mainly emulate dos programs.

至於現在,因為這專案偏於學習使用,剛好趁這機會也多了解一些東西,姑且先以 full x86 base pc為開發目的,若以後有別想法或是難以實現,視情況再修改做法.

2016年7月12日 星期二

GNU lightning jit 應用例子

對模擬器的喜好來自於對遊戲主機童年時期的熱愛(約佔70%),以及本身是資訊人,多少對技術方面的東西會更有興趣些,所以偶而會找找相關資訊看看.

其中剛好看到了一個利用JIT加入效能的範例如下

http://jeffq.com/blog/nds4droid-release-35-beta/

用的是 GNU lightning 這套JIT加速library

https://www.gnu.org/software/lightning

相當有趣.

隨著資訊技術這幾年的發展,很多新的技術都慢慢被應用在模擬器的開發上.

8086 指令解碼

x86 模擬器裝案的進展荒廢許久,最近把顯示卡的部分K一K了解一下,打算重新再來過,反正姑且一試,第一個步驟還是習慣先從CPU本身的核心開始撰寫起,當然16Bit的CPU指令複雜度已經沒像8bit CPU那麼容易了,但我個人覺得比起ARM,x86的8086這顆cpu指令解碼複雜程度相對來說還是簡單許多.

8086這顆cpu的指令已經無法使用拿指令的第一個byte用窮舉法搭配 switch case的方式來做完全的剖析,一定會有重覆的衝突,不過無所謂,只有少數幾個指令需要用第二個byte的 bit 5~3 這三個bits再做一次分析,還是可以用窮舉法,只是某幾個地方需要用到兩層.

最聰明的decode策略應該是完全了解指令的格式規則,然後用樹狀關係圖去分層出解碼的步驟,但這種方法未必會比較快,最笨的窮舉法直接靠table查詢,理論上應該是最快,但就是怕缺漏掉一些項目.

8086 格式
http://aturing.umcs.maine.edu/~meadow/courses/cos335/8086-instformat.pdf

datasheet
http://www.ece.cmu.edu/~ece740/f11/lib/exe/fetch.php?media=wiki:8086-datasheet.pdf

286開始有保護模式,386第一顆32bit cpu,486直接附帶浮點函數計算能力與相關指令,一越新的硬體越複雜,先從簡單開始,至少8086已經可以跑win 3.0了 ( 3.1需要跑在最低286上).

最後不得提醒一下,不要以為官方出版的資料或是規格書之類的東西就100%不會有錯誤,實際上就還是會有可能遇到,而且我在兩分資料中各遇到了兩次....

舉個例子來說


2016年7月7日 星期四

x86 電腦研究心得

看 8086tiny 這專案剛看會給人誤會,以為要模擬PC X86模擬器不會是太複雜的事情,再追究下去,會發現這專案用了很多相當聰明的方式簡化了所包含的CODE數量,但簡化的道理卻因為對硬體沒有夠詳細的了解,也不知所以然來,於是放棄了以這專案為學習的開始,改以 V86 https://github.com/copy/v86 這款js pc的模擬器為學習對象,完整度可以執行到win98不是問題,重點是很紮實地去跑了system bios跟vga bios,追著這專案跑,一跑到VGA那塊馬上發現自己的無知,原來電腦VGA顯卡還是有很多學問,很多對應port的Register各自有各自的功能,然後記憶體排列的原理和規則等等,要搞懂也不是那麼簡單,像這種東西在早期有很多相關的書或是資料,但現在可以找到的說明越來越少,能找到的多數是英文,但解釋的也未必很清楚

http://wiki.osdev.org/VGA_Hardware
這篇有很多vga卡 port的作用和記憶體屬性規則在各種顯示模式下的說明

很多東西還得再細看和實際demo測試....不是說那麼好懂.

2016年1月29日 星期五

z80 , 8008 , 8086 , 6502

純心得文.

GameBoy用的z80特殊修改版(簡化掉一些功能.修改掉一些功能) , 以前實作過 , 所以還算熟 , 定址模式不會很複雜 , 反來是同期的 6502 定址模式多不少,相對複雜 , 但有趣的是後來才知道 z80原來就是 Intel 8008 的相容實作 ,然而在8086這顆Intel 16Bit版本的cpu卻反來充滿了 6502 的一些影子在 ,  不知道這中間是有啥商業合作關係或是設計關係在 , 總之8086有著模仿的影子 , 但模仿對象相似對象卻不是自己上代 8008 ,反來是 相異產品 6502 ,滿有趣的.

目前正在邊學邊實作8086電腦,看到那堆定址模式給我的直覺聯想到的是6502,定址模式複雜沒關係,反正做啥就做啥,一板一眼的應該是還好,但PC模擬器周邊裝置的模擬反來複雜些,目前正在慢慢理解如何實作軟碟機.硬碟.光碟和一些裝置IO這塊,總之東看西看,慢慢來.,..期待有機會完成一個基礎的8086 PC.

目前大概的心得是,PC模擬器似乎不用考慮到如同遊戲機嚴謹的timing問題,顯示的部分也簡單很多,理論上應該會比遊戲機的模擬容易一點,但相對的PC的裝置周邊這塊又是遊戲模擬器所沒有的部分,反來需要比較多功夫.


模擬器兩方向發展議題

過去多數模擬器採用的是直譯式的運作方式,直到現在還是一樣,但俗著近年來很多技術從實驗階段到發展成熟到普遍應用,像是最有名的JIT或是LLVM之類的工具或是概念,也影響到模擬器的實作方式,網路上開始零星(數量還不多)出現一些採用非直譯方式的模擬器,下面就是一個例子

http://andrewkelley.me/post/jamulator.html

多數是採取8bit的遊戲主機為範本,讓異質的機械碼編譯成x86原生碼.

wii模擬器Dolphin中,也看得到模擬模式中有類似含意的選項.

這是非常有趣的嘗試,不過因為技術層次比較高,多數人會先採取將較為簡單的機械碼做轉換,所以才通常是會8bit遊戲主機的模擬器來學習,但實際上如果以實用性來說,CPU 模擬的運算在古早主機中負擔比例其實很低,反來是GPU等等部分模擬代價較高,通常會這樣做多數可能是基於研究或是學習立場,並沒有真的帶來很多好處.

不過如果是近年來的進階機種,cpu模擬耗用運算可能就不低了,這時候這種效能比直譯佳的運作模式,就帶來很多好處.

這種東西其實有很多進階討論的空間,而且不單單能在遊戲模擬器上發揮,試想著ARM與X86透過編譯步驟的方式,就能快速擁有雙邊硬體的相容性,這是多夢幻的"未來"....


跟上面這種往高階領域剛好相反的模擬方式(上面是軟體發展的進步),是由於近年來硬體效能快速發展下產生的,那就是往更低的領域發展,電晶體準確層次的模擬器,也就是說它的模擬基礎是從電路邏輯層開始,這種設計方式反來耗用更高的運算資源,不過有著其他方式無法取代的優點,像是絕對準確的tinimg特性.保證原汁原味的功能等等,目前也已經開始有零星實作出現,但通常是技術宣示性質,執行效能還得做不少改善,才能到實用的地步.

想像一下如果真的是在未來,電腦主機效能強大到無法想像的地步,模擬一台主機所要做的是把遊戲主機拆解,邏輯晶片打開,拍張照,把線路layout匯出描述,接著就可以跑了,也是一件很夢幻的事情...誰知道那天何時到來?  就像是當初誰也想不到現金一台手機的效能,就打死過去一整台桌機一樣.

目前是受限效能,因為邏輯電路是平行的運作方式一層一層下去,從這層次去模擬代價是相當多倍的運算資源,不過讓我發想的倒是這種運作方式在平行運算的超級電腦上似乎還ok,又或者是近年來利用顯卡異構計算的平行處理運算資源輔助?  這似乎也是一個方向.

相關參考
http://www.mobile01.com/topicdetail.php?f=514&t=1799027
http://blog.visual6502.org/2014/10/atari-2600-simulation.html
http://psxdev.ru/news
http://hackaday.com/2014/12/18/counting-transistors-in-the-playstation/
http://sourceforge.net/projects/dice/

ideal很多,不代表我有辦法在現在去做一些想法驗證,多數還是看看資訊.整理資訊而已.