<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6349370086167910319</id><updated>2011-04-21T22:06:41.752-07:00</updated><category term='技術文章/Windows應用'/><category term='技術文章/硬體'/><category term='技術文章/其他'/><category term='技術文章/計算機/Playstation2'/><category term='技術文章/NIOS2'/><category term='技術文章/計算機'/><category term='技術文章'/><category term='技術文章/軟體開發'/><category term='技術文章/Firmware'/><title type='text'>阿~~-y朙的不小格</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>41</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-7076604676942617859</id><published>2009-04-20T21:58:00.000-07:00</published><updated>2009-04-20T22:00:15.049-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/其他'/><title type='text'>Gmail迂迴入口網址</title><content type='html'>&lt;a href="http://mail.google.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/mail.google.com');"&gt;http://mail.google.com&lt;/a&gt; or &lt;a href="https://mail.google.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/mail.google.com');"&gt;https://mail.google.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.gmail.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/www.gmail.com');"&gt;http://www.gmail.com&lt;/a&gt; or &lt;a href="https://www.gmail.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/www.gmail.com');"&gt;https://www.gmail.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://gmail.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/gmail.com');"&gt;http://gmail.com&lt;/a&gt; or &lt;a href="https://gmail.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/gmail.com');"&gt;https://gmail.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://m.gmail.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/m.gmail.com');"&gt;http://m.gmail.com&lt;/a&gt; or &lt;a href="https://m.gmail.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/m.gmail.com');"&gt;https://m.gmail.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://googlemail.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/googlemail.com');"&gt;http://googlemail.com&lt;/a&gt; or &lt;a href="https://googlemail.com/" onclick="javascript:pageTracker._trackPageview ('/outbound/googlemail.com');"&gt;https://googlemail.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://mail.google.com/mail/x/" onclick="javascript:pageTracker._trackPageview ('/outbound/mail.google.com');"&gt;http://mail.google.com/mail/x/&lt;/a&gt; or &lt;a href="https://mail.google.com/mail/x/" onclick="javascript:pageTracker._trackPageview ('/outbound/mail.google.com');"&gt;https://mail.google.com/mail/x/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-7076604676942617859?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/7076604676942617859/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=7076604676942617859' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/7076604676942617859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/7076604676942617859'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2009/04/gmail.html' title='Gmail迂迴入口網址'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-4999938254272710235</id><published>2009-02-27T04:49:00.001-08:00</published><updated>2009-02-27T04:49:44.290-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/硬體'/><title type='text'>轉貼：SPDIF數位傳輸介面概念解析</title><content type='html'>&lt;span class="content"&gt;     &lt;b&gt;SPDIF數位傳輸介面概念解析&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="tiny"&gt;&lt;b&gt;日期：&lt;/b&gt; 2007年12月29日&lt;br /&gt;&lt;b&gt;文章主題：&lt;/b&gt; DAC數位類比轉換套件系列&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;         &lt;span class="content"&gt; S/PDIF，全名為Sony/Philips Digital Interconnect Format，是Sony和Philips這兩大巨頭在80年代為一般家用器材所定制出來的一種數位訊號傳輸介面，基本上是以AES/EBU(也稱為 AES3)專業用數位介面為參考然後做了一些小變動而成的家用版本，可以使用成本比較低的硬體來實現數位訊號傳輸。&lt;br /&gt;&lt;br /&gt; 本文介紹了S/PDIF的整體架構、編碼方式以及各個結構的定義，由於S/PDIF在現今已經是一個最廣泛使用的數位音樂資料介面，所以值得對數位音響器材有興趣的朋友們去好好瞭解一下，希望本篇文章能讓網友們對於S/PDIF有進一步的認識。&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;div style="text-align: center;"&gt; &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/EC_SPDIF_IMG_01.jpg" /&gt; &lt;/span&gt;&lt;/div&gt;  &lt;p&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="content"&gt;S/PDIF簡介&lt;/span&gt;&lt;/span&gt;  &lt;/p&gt;  &lt;p&gt; &lt;span class="content"&gt;S/PDIF，全名為Sony/Philips Digital Interconnect Format，是Sony和Philips這兩大巨頭在80年代為一般家用器材所定制出來的一種數位訊號傳輸介面，基本上是以AES/EBU(也稱為 AES3)專業用數位介面為參考然後做了一些小變動而成的家用版本，可以使用成本比較低的硬體來實現數位訊號傳輸。為了定制一個統一的介面規格，在現今以 IEC 60958標準規範來囊括取代AES/EBU與S/PDIF規範，而IEC 60958定義了三種主要型態： &lt;/span&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;&lt;span class="content"&gt;&lt;li&gt;IEC 60958 TYPE 1 Balanced ─ 三線式傳輸，使用110 Ohm阻抗的線材以及XLR接頭，使用於專業場合。&lt;/li&gt; &lt;li&gt;IEC 60958 TYPE 2 Unbalanced ─ 使用75 Ohm阻抗的銅軸線以及RCA接頭，使用於一般家用場合。&lt;/li&gt; &lt;li&gt;IEC 60958 TYPE 2 Optical ─ 使用光纖傳輸以及F05光纖接頭，也是使用於一般家用場合 &lt;/li&gt; &lt;/span&gt;  &lt;p&gt; &lt;span class="content"&gt;事實上，IEC 60958有時會簡稱為IEC958，而IEC 60958 TYPE 1即為AES/EBU(或著稱為AES3)介面，而IEC 60958 TYPE 2即為S/PDIF介面，而雖然在IEC 60958 TYPE 2的接頭規範裡是使用RCA或著光纖接頭，不過近年來一些使用S/PDIF的專業器材改用BNC接頭搭配上75 Ohm的同軸線以得到比較好的傳輸品質，下表為AES/EBU與S/PDIF的比較表。 &lt;/span&gt;&lt;/p&gt;  &lt;p&gt; &lt;table style="border: 0px solid rgb(0, 0, 0); background-color: rgb(58, 58, 58);" align="center" border="0" cellpadding="2" cellspacing="1" width="600"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td colspan="3" align="center" bgcolor="#ffffff"&gt;    &lt;span style="font-weight: bold;"&gt;    AES/EBU與S/PDIF比較表    &lt;/span&gt;   &lt;/td&gt;  &lt;/tr&gt;   &lt;tr&gt;   &lt;td bgcolor="#ffffff"&gt; &lt;/td&gt;   &lt;td align="center" bgcolor="#ffffff"&gt;AES/EBU&lt;/td&gt;   &lt;td align="center" bgcolor="#ffffff"&gt;S/PDIF&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td bgcolor="#ffffff"&gt;線材&lt;/td&gt;    &lt;td bgcolor="#ffffff"&gt;110 Ohm屏蔽絞線&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;75 Ohm同軸線或是光纖線&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td bgcolor="#ffffff"&gt;接頭&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;XLR 3 Pin接頭&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;RCA或BNC接頭&lt;/td&gt;   &lt;/tr&gt;  &lt;tr&gt;   &lt;td bgcolor="#ffffff"&gt;最大位元數&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;24 Bits&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;標準為20 Bits(可支援到24 Bits)&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;td bgcolor="#ffffff"&gt;訊號電平&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;3 ~ 10V&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;0.5 ~ 1V&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td bgcolor="#ffffff"&gt;編碼&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;雙相符號編碼(Biphase Mark Code)&lt;/td&gt;    &lt;td bgcolor="#ffffff"&gt;雙相符號編碼(Biphase Mark Code)&lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;span class="content"&gt;&lt;br /&gt; &lt;/span&gt;&lt;p&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="content"&gt;IEC958使用的編碼方法&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;  &lt;div style="text-align: center;"&gt; &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/EC_SPDIF_FIG_04.png" /&gt; &lt;br /&gt;圖說：雙相符號編碼(Biphase Mark Code)的運作原理示意圖。 &lt;/span&gt;&lt;/div&gt;  &lt;p&gt; &lt;span class="content"&gt;IEC958在傳輸資料時使用雙向雙相符號編碼(Biphase Mark Code)，簡稱BMC，屬於一種相位調制(phase modulation)的編碼方法，是將時鐘訊號和資料訊號混合在一起傳輸的編碼方法。 &lt;/span&gt;&lt;/p&gt;  &lt;p&gt; &lt;span class="content"&gt;其原理是使用一個兩倍於傳輸位元率(Bit Rate)的時鐘頻率做為基準，把原本一個位元資料拆成兩部份，當資料為1的時後在其時鐘週期內轉變一次電位(0-&gt;1或1-&gt;0)讓資料變 成兩個不同電位的資料，變成10或01，而當資料為0時則不轉變電位，變成11或00。同時每一個位元開頭的電平與前一個位元結尾電平要不同，這樣接收端 才能判別每一個位元的邊界。 &lt;/span&gt;&lt;/p&gt;  &lt;div style="text-align: center;"&gt; &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/DAC1229-1.jpg" /&gt; &lt;/span&gt;&lt;/div&gt;   &lt;p&gt; &lt;span class="content"&gt;使用BMC編碼可以讓傳輸端與接收端只需一條資料線就可以將資料正確的傳送與接收，並且在收送兩端可以保持 比較好的同步性，這是由於BMC格式的電位極性一定會在兩個位元週期之間變換，這樣接收端可以不用理會實際接收到的電為是0或1，只需判別與上一個電平的 極性是相同或相反即可。此外，BMC編碼可以讓傳輸線保持在接近零的平均直流電位，除了可以降低傳輸需要耗費的功率之外，也可以降低實體電磁干擾，讓資料 正確性更高。 &lt;/span&gt;&lt;/p&gt;  &lt;span class="content"&gt;&lt;br /&gt; &lt;/span&gt;&lt;p&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="content"&gt;IEC958通訊協定架構&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;  &lt;div style="text-align: center;"&gt; &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/EC_SPDIF_FIG_01.png" /&gt; &lt;/span&gt;&lt;/div&gt;  &lt;p&gt; &lt;span class="content"&gt;S/PDIF與AES/EBU主要是做為傳遞PCM格式訊號之用，例如48kHz的DAT以及 44.1kHz的CD，不過現今也有用來傳遞壓縮過的多聲道訊號。標準傳遞兩聲道訊號的架構如上圖所示，最上面為由192個框架(Frame)構成的區塊 (Block)。而每個Frame儲存了兩個聲道的一組取樣訊號(Sample)，分為Channel A與Channel B兩個聲道。而每組Sample由一個子框架(Sub Frame)構成，也就是一個Frame裡有兩個Sub Frame。Sub Frame的資料長度為32 Bits，裡頭內含了頭碼(Preamble)、輔助資料(Aux. Data)、音訊資料(Audio Data)、以及四個位元的資訊與檢查碼。也就是說，一個Sub Frame為32 Bits，也就4 Bytes，而一個Frame為8 Bytes，而一個Block為192 x 8 = 1536 Bytes，而每個Block總共可以傳遞192個雙聲道Sample。 &lt;/span&gt;&lt;/p&gt;  &lt;span class="content"&gt;&lt;br /&gt; &lt;/span&gt;&lt;p&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="content"&gt;子框架(Sub Frame)細部解說&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;  &lt;div style="text-align: center;"&gt; &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/EC_SPDIF_FIG_02.png" /&gt;&lt;br /&gt;圖說：IEC958內的基本資料結構 ─ 子框架(Sub Frame)結構圖。 &lt;/span&gt;&lt;/div&gt;  &lt;p&gt; &lt;span class="content"&gt;要瞭解IEC958的資料結構了話，我們有必要要先瞭解子框架(Sub Frame)的詳細結構，一個Sub Frame如上圖所示區分成好幾個部份，我們先一一表列如下：  &lt;/span&gt;&lt;/p&gt;  &lt;p&gt; &lt;table style="border: 0px solid rgb(0, 0, 0); background-color: rgb(58, 58, 58);" align="center" border="0" cellpadding="4" cellspacing="1" width="95%"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td align="center" bgcolor="#ffffff" width="80"&gt;位元位置&lt;/td&gt;   &lt;td align="center" bgcolor="#ffffff" width="150"&gt;區塊名稱&lt;/td&gt;   &lt;td align="center" bgcolor="#ffffff"&gt;功能說明&lt;/td&gt;  &lt;/tr&gt;   &lt;tr&gt;   &lt;td align="center" bgcolor="#ffffff"&gt;0-3&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;頭碼(Preamble)&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;    用來表示一個Sub Frame的開頭，有三種型態，分別表示該Sub Frame為Channel A、Channel B或著是一個Block的起始Sub Frame(為Channel A)。   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;td align="center" bgcolor="#ffffff"&gt;4-7&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;輔助資料(Aux. Data)&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;    原始此區塊的設計是用來傳遞一些使用者自行添加的資訊，不過目前比較常見的用途是當音訊資料超過20Bit取樣時，這四個Bit用來儲存多出的取樣Bit，比如說當要傳送24Bit取樣的資料時，用來存放末四個Bit的音訊資料。   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center" bgcolor="#ffffff"&gt;8-27&lt;/td&gt;    &lt;td bgcolor="#ffffff"&gt;音訊資料(Audio Data)&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt; 存放實際的取樣資料，長度為20 Bit，以LSB優先的方式傳送，當取樣低於20 Bit時，沒有用到的LSB Bits要設定為零，舉例來說，當我們要傳送16 Bit的資料時，只會用到12-27 Bit的位置(LSB在12 Bit)，而8-11 Bit為零。 &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center" bgcolor="#ffffff"&gt;28&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;有效位元(Validity Bit)&lt;/td&gt;    &lt;td bgcolor="#ffffff"&gt; 此位元設定了這一個Sub Frame內的資料是不是正確，如果設定為0，代表此Sub Frame內的資料是正確可被接收的，反之如果此Bit為1，則代表接收端應該忽略此組Sub Frame。比如說CD轉盤讀取CD資料時若是有某一個Sample讀不到就會將代表該組Sample的Sub Frame中的有效位元設為1。 &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center" bgcolor="#ffffff"&gt;29&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;使用者位元(User Bit)&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;     此位元為使用者自行定義的位元，每組Sample傳送一位元，直到192組Sample傳完後組成成192位元的資訊，兩聲道各自有一組192位元的使用者資訊。   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center" bgcolor="#ffffff"&gt;30&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;通道狀態位元(Channel Status Bit)&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt; 此位元與使用者位元一樣，每組Sample傳送一位元，最後組成兩聲道各自一組192位元的通道狀態資訊(Channel Status)。這個192位元通道狀態資訊分為專業(Professional)與一般家用(Consumer)兩種不同的結構，以第一個位元決定，設 為1的時後為Professional模式，設為0的時後為Consumer模式。 &lt;/td&gt;   &lt;/tr&gt;  &lt;tr&gt;   &lt;td align="center" bgcolor="#ffffff"&gt;31&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;同位元檢查位元(Parity Bit)&lt;/td&gt;   &lt;td bgcolor="#ffffff"&gt;   同位元檢查是用來判別是否有奇數個位元是發生錯誤，是一種簡便錯誤檢查方法，這邊是使用偶位同位元檢查(Even Parity Check)。   &lt;/td&gt;  &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;span class="content"&gt;&lt;br /&gt; &lt;/span&gt;&lt;p&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="content"&gt;子框架內的頭碼(Preamble)定義&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;  &lt;div style="text-align: center;"&gt; &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/EC_SPDIF_FIG_05.png" /&gt; &lt;/span&gt;&lt;/div&gt;  &lt;p&gt; &lt;span class="content"&gt;如前文所述，頭碼(Preamble)是用來表示一個Sub Frame的開頭，主要有X、Y、Z三種組態代表不同的意義，X代表此時是傳送A通道的Sub Frame、Y代表是傳此時是傳送B通道、而Z比較特別，是代表此時是傳送A通道，並且是一個Block的起始Sub Frame。 &lt;/span&gt;&lt;/p&gt;  &lt;p&gt; &lt;span class="content"&gt;而在上頭的表格裡的資料數值是Sub Frame中其它的資料經過BMC編碼之後再加到整個Sub Frame前頭的資料數值，所以總共是八碼，代表四個位元的時序。此外比較特別的是除了有X、Y、Z三種組態之外，上面的表格還列出了另外一組與原本資料 向位相反的數值，要使用哪一組數值是依照前一組Sub Frame中最尾端的電平而定，當前一組Sub Frame為最尾端的電平0時用左邊那一列數值，為1的時後用右邊那一列，這樣一樣接收端才能正確處理。 &lt;/span&gt;&lt;/p&gt;   &lt;div style="text-align: center;"&gt; &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/EC_SPDIF_FIG_06.png" /&gt;&lt;br /&gt;圖說：兩組Preamble組態實際呈現的型態，仔細觀察後可發現是不符合BMC編碼定義的。 &lt;/span&gt;&lt;/div&gt;  &lt;p&gt; &lt;span class="content"&gt;再來是Preamble比較特別的地方，我們若是觀察上圖的波型，可以發現每個Preamble組態都有兩 處是不符合BMC規範中「每一個位元開頭的電平與前一個位元結尾電平要不同」的定義，尤其是一開頭的000或111就不符合BMC編碼的定義了。這樣子的 設計是用來讓接收端很清楚的得知每個Sub Frame的起始點，只需簡單的檢查資料中不符合BMC編碼定義的位置就可以了。 &lt;/span&gt;&lt;/p&gt;  &lt;div style="text-align: center;"&gt;  &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/EC_SPDIF_FIG_03.png" /&gt;&lt;br /&gt;圖說：在一個區塊(Block)中，Preamble為Z組態的時後代表一個區塊的起始點。 &lt;/span&gt;&lt;/div&gt;  &lt;span class="content"&gt;&lt;br /&gt; &lt;/span&gt;&lt;p&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="content"&gt;通道狀態(Channel Status)的結構&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;  &lt;p&gt; &lt;span class="content"&gt;如前文所述，每組Sub Frame中有一位元的通道狀態位元，在一個Block有192組Frame，可以構成192位元的通道狀態結構(Channel Status Structure)，而兩聲道各自有一組192位元的使用者資訊。這這個192位元的通道狀態結構主要有兩種不同的結構，由第一個位元來決定，當第一個 位元為0時代表一般家用(Consumer)結構，第一個位元為1時代表專業用(Professional)結構，分別為下面這兩張結構圖表。 &lt;/span&gt;&lt;/p&gt;  &lt;div style="text-align: center;"&gt;  &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/EC_SPDIF_FIG_07.png" /&gt;&lt;br /&gt;圖說：一般家用通道狀態結構圖(Consumer Channel Status Structure)。 &lt;/span&gt;&lt;/div&gt; &lt;span class="content"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: center;"&gt; &lt;span class="content"&gt;&lt;img src="http://www.diyzone.net/images2/EC_SPDIF_FIG_08.png" /&gt;&lt;br /&gt;圖說：專業用通道狀態結構圖(Professional Channel Status Structure)。 &lt;/span&gt;&lt;/div&gt;  &lt;p&gt; &lt;span class="content"&gt;而實際使用上，上面這兩個圖表只能當做參考使用，因為通道狀態結構有許多種不同的版本，到目前為止世面上許 多不同器材所遵循的版本也不儘相同，甚至有一些器材會忽略不處理通道狀態，舉例來說，有許多器材並不會處理一般家用版本中關於內容保護的資訊或是取樣頻率 的資訊...等等。所以本文並不打算一一介紹通道狀態裡的詳細定義，有興趣的朋友可以自行參考IEC60958、AES3...等技術文件。 &lt;/span&gt;&lt;/p&gt;  &lt;span class="content"&gt;&lt;br /&gt; &lt;/span&gt;&lt;p&gt; &lt;span style="font-weight: bold;"&gt;&lt;span class="content"&gt;結語&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;  &lt;p&gt; &lt;span class="content"&gt;S/PDIF，或著稱為IEC958、IEC 60958、AES/EBU、AES3、TC84...等等名稱，是一個在數位音頻訊號早期就發展出來的一個傳輸介面與協定，從硬體介面規範至通訊協定皆 有其規範在，不過由於時代變化迅速，為了因應各種新的需求所以也產生出許許多多不同的標準，甚至在同一個標準裡也有不同的版本。 &lt;/span&gt;&lt;/p&gt;  &lt;p&gt; &lt;span class="content"&gt;不過大體上各種不同的標準與版本中都保留了彼此之間的相容性，而對於整個區塊(Block)、框架(Frame)、子框架(Sub Frame)的定義都相同，不同之處在於對於硬體介面上以及額外的通道資訊上的定義不同，並不影響實際音樂數位資料的傳遞。 &lt;/span&gt;&lt;/p&gt;  &lt;p&gt; &lt;span class="content"&gt;本文介紹了S/PDIF的整體架構、編碼方式以及各個結構的定義，由於S/PDIF在現今已經是一個最廣泛使用的數位音樂資料介面，所以值得對數位音響器材有興趣的朋友們去好好瞭解一下，希望本篇文章能讓網友們對於S/PDIF有進一步的認識。 &lt;/span&gt;&lt;/p&gt;  &lt;span class="content"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-4999938254272710235?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/4999938254272710235/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=4999938254272710235' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/4999938254272710235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/4999938254272710235'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2009/02/spdif.html' title='轉貼：SPDIF數位傳輸介面概念解析'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-7767453775508843501</id><published>2009-02-20T07:37:00.001-08:00</published><updated>2009-02-20T07:37:43.140-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/硬體'/><title type='text'>设计家用电器电路控制板时的EMC方法</title><content type='html'>&lt;h1&gt;设计家用电器电路控制板时的EMC方法 &lt;/h1&gt;                                    &lt;h4&gt;2008-07-25 13:36:34   作者：刘琦   来源：&lt;a href="http://www.eeworld.com.cn/mndz/2008/0725/article_960.html" target="_blank"&gt;今日电子&lt;/a&gt;&lt;/h4&gt;                                                                       &lt;p&gt;　　家电控制板的小体积，低成本决定了在线路中不会使用高成本的材料来解决其电磁干扰问题。家电控制板的干扰主要来自三大方面：一是控制板本身产生的干扰，二是来自负载的干扰，三是来自线路上的干扰。解决这些干扰可以分别采用不同的方案来达成。&lt;/p&gt; &lt;p&gt;　　&lt;strong&gt;控制板自身的干扰&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;　　&lt;strong&gt;1 控制板本身产生的干扰&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;　　家电控制板中常用的继电器、可控硅以及高频时钟等，都可能成为小家电控制板的自身干扰源。对于以上干扰，可以从以下方面入手来解决：&lt;/p&gt; &lt;p&gt;　　● 在继电器线圈增加续流二极管，消除断开线圈时产生的反电动势干扰。 &lt;/p&gt; &lt;p&gt;　　● 在继电器接点两端并接火花抑制电路(一般是RC串联电路，电阻一般选几千欧到几十千欧，电容选0.01μF，以减小电火花影响)。&lt;/p&gt; &lt;p&gt;　　● 在电路板上每个IC上并接一个0.01～0.1μF高频电容，以减小IC对电源的影响。但应注意高频电容的布线，连线应靠近电源端并尽量粗短，否则，等于增大了电容的等效串联电阻，而这会影响滤波效果。&lt;/p&gt; &lt;p&gt;　　● 布线时应避免90°折线，并尽量减少高频噪声发射。&lt;/p&gt; &lt;p&gt;　　● 在可控硅两端并接RC抑制电路，减小可控硅产生的噪声(该噪声严重时可能会把可控硅击穿)。&lt;/p&gt; &lt;p&gt;　　● 注意晶振布线。晶振与芯片引脚应尽量靠近，并用地线把时钟区隔离起来，晶振外壳要接地并固定。最好在能使用低速晶振的场合尽可能选用低速晶振。 &lt;/p&gt; &lt;p&gt;　　● 对电路板合理分区(如强、弱信号，数字、模拟信号)。尽可能把干扰源(如电机、继电器)与敏感元件(如单片机)远离。&lt;/p&gt; &lt;p&gt;　　● 交流端用电感电容滤波：去掉高频低频干扰脉冲，VCC和GND之间接电解电容及瓷片电容，以去掉高、低频干扰信号。&lt;/p&gt; &lt;p&gt;　　&lt;strong&gt;2 控制板本身的传导干扰&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;　　为了防止控制板电路产生的传导干扰，可在电路的进入口(即AC两端)并接上一个电容C，图1所示是一个简单的电容抗扰电路连接图。图中的电容属 于安全电容，但必须在该电容的两端并联一个安全电阻，以防止电源线拔插时电源线插头长时间带电。因为安全标准规定，当正在工作之中的机器电源线被拔掉时， 在两秒钟内，电源线插头两端所带的电压(或对地电位)应小于原来电压的30％。&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.eeworld.com.cn/uploadfile/backup/uploadfile/200807/20080717111029880.gif" /&gt;&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p&gt;　　图1 电容抗扰电路&lt;/p&gt; &lt;p&gt;　　该电容必须经过安全检测部门认证过后才能使用。电容的耐压一般都标有安全认证标志和AC250V或AC275V字样，但其真正的直流耐压应达到2 000 V以上。而且在使用的时候，不要随便用AC250V或DC400V之类的电容来代用。&lt;/p&gt; &lt;p&gt;　　抗扰电容一般都选用纹波电流比较大的聚脂薄膜安全电容，这种电容体积一般都很大，允许瞬间充放电的电流也很大，即内阻比较小。而普通电容纹波电 流的指标一般都很小，动态内阻较大，因此，用普通电容代替安全电容，除了耐压条件不能满足以外，一般纹波电流指标也难以满足要求。&lt;/p&gt; &lt;p&gt;　　实际上，光靠用安全电容就想把传导干扰信号完全滤除是不可能的。因为干扰信号的频谱非常宽，基本覆盖了几十千赫到几百兆赫甚至上千兆赫的频率范 围。一般对低端干扰信号，其滤除需要很大容量的滤波电容，但受到安全条件的限制，电容的容量不能太大；而对高端干扰信号的滤除，大容量电容的滤波性能又极 差，特别是聚脂薄膜电容的高频性能一般都比较差，并且聚脂薄膜介质的高频响应特性与陶瓷或云母相比相差很远，此外，一般聚脂薄膜介质都具有吸附效应，会降 低电容器的工作频率。聚脂薄膜电容工作频率范围大约在1MHz，超过1MHz时其阻抗将显著增加。因此，抑制电子控制板本身产生的传导干扰除了选用这种电 容进行滤波以外，一般还要同时选用多个电感滤波器一起组合来对干扰进行滤波。电感滤波器属于低通滤波器，但电感滤波器也有很多种类和无数种规格(如差模、 共模以及高频、低频)等，每种电感主要都是针对某一小段频率的干扰信号而起滤除作用，而对其他频率的干扰信号作用不大。电感量很大的电感，其线圈匝数很 多，分布电容也很大，高频信号会通过分布电容旁路掉，另外，导磁率很高的磁芯，其工作频率也不高。目前，国内大量使用的电感滤波器磁芯的工作频率大多数都 在75MHz以下，对于工作频率要求比较高的场合，必须选用高频环形磁芯（高频环形磁芯导磁率一般都不高，但其漏感特别小）。&lt;/p&gt; &lt;p&gt;　　&lt;strong&gt;负载干扰&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;　　家电中的负载包括线性负载(如热水器)和非线性负载(豆浆机，绞肉机等)。非线性负载是一种频谱极宽的干扰源，其抑制方法主要有两种：一是从非 线性负载(如电机)本身入手；由于不恰当的操作、接触器的接触不良、炭刷不干净等原因，都会产生数倍于正常运转时的干扰情况，为了减少干扰，应当保证接触 器的接触可靠、开关动作的正常和触头的压力，还要保持炭刷和换向器的干净，保证炭刷本身的质量和换向器的光洁度；同时保证炭刷对换向器有适当的压力；最后 还要使机座的固定可靠，避免机械运转时引起的运转不稳。 其二则是采用必要的电气滤波方式，其电路连接如图2所示。&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.eeworld.com.cn/uploadfile/backup/uploadfile/200807/20080717111029539.gif" /&gt;&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p&gt;　　图2 负载的电器滤波电路&lt;/p&gt; &lt;p&gt;　　该电路的目的是为干扰电势提供一个低阻抗的通路，以抑制干扰值。图2中，C1为电感成分较小的电容，一般为几十至几百纳法；C2选穿心电容，一 般为1～4.7 nF。增加该电容的目的是为了抑制噪声，但电容的安装位置不同，以甚高频段的干扰抑制效果会有很大变化，所以，安装时要特别注意电容的接地外壳应与电动机 座或金属外壳的最短连接。同时应在连线时使电容器的输入、输出部分的电磁耦合尽可能地减少。&lt;/p&gt; &lt;p&gt;　　此外，还有一组典型的△形干扰抑制器电路，可同时抑制对称和不对称干扰。其具体电路如图3所示。&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.eeworld.com.cn/uploadfile/backup/uploadfile/200807/20080717111029563.gif" /&gt;&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p&gt;　　图3 Δ形干扰抑制电路&lt;/p&gt; &lt;p&gt;　　&lt;strong&gt;线路干扰&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;　　线路干扰的干扰源主要来自外界电磁场在导线上感应出的电压，电源线上其它电器发射的和感性负载通断造成的干扰，以及浪涌(雷击)产生的干扰等。&lt;/p&gt; &lt;p&gt;　　&lt;strong&gt;1 电磁场在电缆上的感应&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;　　电磁场在导线中感应出的电压一般是共模电压，而负载上的电压则以系统中的公共导体或大地为参考点。一般以系统中的参考地线面为参考点。对于多芯 电缆来说，这意味着电缆中的所有导体都暴露在同一个场中，它们上面所感应的电压取决于每根导体与参考点之间的阻抗。抑制干扰的方法可以使用共模移值法，其 原理图如图4所示。&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.eeworld.com.cn/uploadfile/backup/uploadfile/200807/20080717111029637.gif" /&gt;&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p&gt;　　图4共模移值干扰抑制电路&lt;/p&gt; &lt;p&gt;　　图4中共模扼流圈的特殊绕制方法决定了它仅对共模电流有抑制作用，而对电路工作所需要的差模电流没有影响。因此，共模扼流圈是解决共模干扰的理 想器件。理想的共模扼流圈的低频共模抑制作用较小，而随着频率的升高，抑制效果增加。这与平衡电路低频共模抑制比高，随着频率升高平衡性变差，共模抑制比 降低的特性正好相反，因此它们具有互补性。所以，在平衡电路中使用共模扼流圈后，电路可在较宽的频率范围内保持较高的共模抑制比。&lt;/p&gt; &lt;p&gt;　　&lt;strong&gt;浪涌干扰&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;　　浪涌是指电源电压和电流的变动，负载开关的闭合、自然界的雷击都可能引起浪涌，且其危害较大，有时可能引起振荡甚至烧坏整个系统。家用电器一般不会直接受到雷电的干扰，大多是通过传导线路中的感应电流或电压引起的骚扰。良好的接地是解决这一干扰的有效手段。&lt;/p&gt; &lt;p&gt;　　防止浪涌干扰的常用器件有气体放电管、金属氧化物压敏电阻(MOVS)和硅瞬变吸收二级管(TVS)。图5所示是采用TVS的浪涌抑制电路。&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.eeworld.com.cn/uploadfile/backup/uploadfile/200807/20080717111030109.gif" /&gt;&lt;/p&gt; &lt;p&gt;　　&lt;/p&gt; &lt;p&gt;　　图5 采用TVS的浪涌抑制电路&lt;/p&gt; &lt;p&gt;　　&lt;strong&gt;结束语&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;　　电磁兼容是家电的一个重要衡量标准参数。由于家电的种类繁多，结构复杂，因此，对其共性技术的研究极为重要。本文对家电共有部件的EMC进行了分析。这些分析对于其他的小家电的电磁兼容研究也具有一定的实际意义。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-7767453775508843501?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/7767453775508843501/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=7767453775508843501' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/7767453775508843501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/7767453775508843501'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2009/02/emc.html' title='设计家用电器电路控制板时的EMC方法'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-6486013534353442504</id><published>2009-01-18T06:29:00.000-08:00</published><updated>2009-01-18T06:31:40.230-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/其他'/><title type='text'>PSP用parade battery降級v1.5方法</title><content type='html'>&lt;span style="color: rgb(255, 0, 0);"&gt;任何普通電池都可以變成超級電池，用來給任何現在市面上的PSP降級。電玩巴士完全測試成功。&lt;/span&gt; &lt;p&gt;　　&lt;span style="color: rgb(0, 51, 255);"&gt;測 試中發現使用某些記憶棒完成刷機所有操作後，機器無法啟動黑屏，這些有問題的記憶棒不是單指組棒，原裝棒一樣會出現(原因還未找到)，刷機失敗也不要擔 心，因為只要有電池和記憶棒就能反覆刷機，所以只要能進入刷機菜單就不存在磚頭，當你刷機失敗後，請換個記憶棒重新製作記憶棒和電池，再刷一次。&lt;/span&gt;&lt;br /&gt;       ____       __      ____&lt;br /&gt;      /\  _`\    /\ \    /\  _`\&lt;br /&gt;      \ \ \/\_\  \_\ \___\ \ \/\ \&lt;br /&gt;       \ \ \/_/_/\___  __\\ \ \ \ \&lt;br /&gt;        \ \ \L\ \/__/\ \_/ \ \ \_\ \&lt;br /&gt;         \ \____/   \ \_\   \ \____/&lt;br /&gt;          \/___/     \/_/    \/___/              &lt;/p&gt;&lt;p&gt;　　PANDORA'S BATTERY&lt;br /&gt;　　　　潘多拉的電池&lt;br /&gt;             =================&lt;br /&gt;一個通用反變磚/降級程序－潘多拉項目發佈，這個項目是由著名的Team C+D小組完成。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;準備：&lt;/strong&gt;&lt;br /&gt;- 普通原裝PSP電池，注意最好準備兩塊(一塊備用啟動PSP)。(第三方生產電池可以，但是便宜的組電不行)&lt;br /&gt;- 一個容量大於32MB的普通Memory Stick Pro Duo記憶棒(4G不可以，8G可以，組棒也可以)&lt;br /&gt;- 一個擁有1.5核心系統的PSP(1.5核心系統包括以下系統： OE、M33 、WC、1.5)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;安裝：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;1&lt;strong&gt;-&lt;/strong&gt; 解壓縮下載到的傻瓜包&lt;br /&gt;&lt;br /&gt;2- 連接你的PSP和電腦，並且保證PSP內有前面準備的記憶棒。&lt;br /&gt;&lt;br /&gt;3- 在PSP上格式化記憶棒，進入「系統設定(System setting)」，選擇「格式化記憶棒(Format Memory Stick)」。&lt;br /&gt;&lt;br /&gt;4- 然後在電腦上DOS窗口用下載到的壓縮包內的mspformat文件夾內的mspformat.exe格式化記憶棒，在這一步我們為了輸入方便，把mspformat.exe文件複製到電腦C盤的根目錄下，以下都以這樣的方式作講解。&lt;/p&gt;&lt;p align="center"&gt;確認電腦和PSP通過USB數據線相連，且PSP打開USB模式，然後回到電腦按下圖操作進入「運行」&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823212500951.gif" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="center"&gt;在窗口內輸入cmd&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823212500823.gif" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="center"&gt;進入DOS窗口後可能不在根目錄，你需要輸入cd\然後按回車，就到了根目錄C:\&gt;&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823213644656.gif" /&gt;&lt;br /&gt;因為我們前面已經把mspformat.exe複製到了C盤，所以直接在根目錄C:\&gt;下輸入mspformat.exe i 後按回車 &lt;/p&gt;&lt;p align="center"&gt;注意&lt;strong&gt;i&lt;/strong&gt;代表記憶棒的盤符&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823221319957.gif" /&gt;&lt;br /&gt;出現Drive succesfully formatted,and partition moved.就表示格式化成功，進行下一步驟，否則請重新操作。 &lt;/p&gt;&lt;p align="left"&gt;5- 然後關閉USB連接，關閉且重新啟動PSP，再開啟usb與電腦連接，這時在電腦上查看記憶棒內已經沒有任何內容(&lt;span style="color: rgb(255, 0, 0);"&gt;格式化後這步操作很重要，沒有完成此操作將導致後續步驟黑屏死機&lt;/span&gt;)。&lt;br /&gt;&lt;br /&gt;6- 把壓縮包內的PSP文件夾複製到記憶棒根目錄，再把傻瓜包內UPDATE.PBP複製到記憶棒根目錄&lt;br /&gt;&lt;br /&gt;7- 關閉USB連接，回到PSP系統，在PSP系統上運行Pandora's Battery Firm. Installer(&lt;span style="color: rgb(255, 0, 0);"&gt;如果運行後黑屏死機請檢查第4-5步；如果開機黑屏後記憶棒無法識別，請找一台有自製系統的PSP，插入這個記憶棒，按住R開機進入恢復模式，然後用USB把PSP和電腦連接，打開USB連接&lt;span style="color: rgb(0, 0, 0);"&gt;Toggle USB&lt;/span&gt;，在電腦上把記憶棒格式化一遍，或者找台Sony的數碼相機/DV把記憶棒插入，用相機格式化一遍，記憶棒就恢復正常了，然後從第1步重新做一遍&lt;/span&gt;。&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823205731178.jpg" /&gt;&lt;br /&gt;　進入程序後在下圖畫面按X，這個程序將在記憶棒根目錄下生成固件文件夾和一個msipl.bin文件。&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823205731152.gif" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;　　生成文件成功後出現Done with success,auto-exiting in 10 seconds.表示成功且10秒後自動退出。&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823205731347.gif" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;8- 連接PSP和電腦，開啟USB。&lt;br /&gt;&lt;br /&gt;9- 然後在電腦上的DOS窗口運行壓縮包內的msinst文件夾下的msinst.exe，通過這個程序把msipl.bin文件的IPL寫入到記憶棒內某個特殊區域(&lt;span style="color: rgb(0, 0, 255);"&gt;具體操作方法與第4步相同&lt;/span&gt;)。&lt;/p&gt;&lt;p align="center"&gt;在C:\&gt;下輸入msinst.exe i i:\msipl.bin後按回車，就會看到下圖畫面&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823221235726.gif" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;10- 再次斷開USB，回到PSP系統。&lt;br /&gt;11- 在PSP系統內執行Pandora's Battery Creator程序，這個程序將修改你的電池把它變成能降級的電池。&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823205731597.jpg" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="center"&gt;運行程序後，出現下圖菜單：&lt;/p&gt;&lt;p align="left"&gt;Current serial原電池序號：0x12345678(根據每個人電池不同號碼有所不同)&lt;/p&gt;&lt;p align="left"&gt;按X---------刷寫成降級用潘多拉電池(神奇電池)&lt;br /&gt;按口--------恢復成普通電池&lt;br /&gt;按O---------恢復成普通電池(自動供電模式)&lt;br /&gt;按三角-----備份電池內信息文件eeprom.bin到記憶棒根目錄&lt;br /&gt;按L+R-----從記憶棒根目錄把電池內信息文件eeprom.bin刷回電池&lt;br /&gt;按HOME-什麼都不運行，退出程序&lt;/p&gt;&lt;p align="left"&gt;Writing serial 0xFFFFFFFF. 寫入後的電池序號&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823205731463.gif" /&gt;&lt;br /&gt;執行程序後，你將看到讓你選擇把電池轉換為不同模式的，我們需要按X修改電池，完成後會自動退出。 &lt;/p&gt;&lt;p&gt;12- 完成上面操作後祝賀你你擁有 "Magic Memory Stick"記憶棒和"JigKick Battery"神奇電池(潘多拉)。&lt;/p&gt;&lt;p align="left"&gt;&lt;strong&gt;用法：&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;注意必須同時使用上面製作的記憶棒和電池才能恢復磚頭或者降級。&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;- 把前面製作好的記憶棒放入你要降級的PSP&lt;br /&gt;&lt;br /&gt;- 然後不要插電源，把前面製作好的電池放入PSP，保證電池內有超過50%的電量，不足時請充電，放入電池後，機器的所有燈將都會亮同時會自動啟動，不能啟動可能是電量不足或需要手動開啟PSP電源。&lt;br /&gt;&lt;br /&gt;- 這時PSP屏幕上就會出現一個菜單，按照菜單提示操作：&lt;br /&gt;第一項是按X降級到1.5。&lt;br /&gt;第二項是按O備份nand內文件到記憶棒根目錄nand-dump.bin。&lt;br /&gt;第三項是按口從記憶棒根目錄恢復nand-dump.bin文件到PSP的nand內。(恢復時需要把nand-dump.bin重命名為為nandimage.flash)&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823225248132.gif" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="center"&gt;按X開始解包固件文件&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823225248884.gif" /&gt;&lt;br /&gt;下面畫面就是開始刷寫1.5固件確認菜單，按X確認開始刷機&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823225248200.gif" /&gt;&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823225248629.gif" /&gt;&lt;br /&gt;　到達100%完成後，按X自動關閉PSP電源，重新啟動PSP，恭喜你這時你將得到的是1.5系統的PSP&lt;br /&gt;&lt;img src="http://psp.tgbus.com/UploadFiles/200708/20070823225248334.gif" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="left"&gt;Q：神奇電池如何使用？&lt;br /&gt;A：需製作好的記憶棒配合，將電池放入電池倉後無需任何操作，讀取一小段時間後自動進入刷機界面。&lt;br /&gt;&lt;br /&gt;Q：神奇電池刷寫是不可逆的嗎？&lt;br /&gt;A：不是。神奇電池可以刷回普通電池（在電池刷寫程序界面按口鍵），刷回的電池使用無任何問題。&lt;br /&gt;&lt;br /&gt;Q：這個過程中有風險嗎？或者說PSP刷失敗會怎麼樣？&lt;br /&gt;A：基本上每風險，難度在製作電池和記憶棒，只要製作成功，可以對機器反覆刷，直到你覺得爽了。&lt;br /&gt;&lt;br /&gt;Q：神奇電池如何充電？&lt;br /&gt;A：和普通電池一樣。&lt;br /&gt;&lt;br /&gt;Q：記憶棒會受損嗎？&lt;br /&gt;A：不會，可以正常使用&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注意事項和使用限制&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;- Memory Stick 中的固件並不是完整的 1.50 固件，而是一個最小化版本。因&lt;br /&gt; 此，並不是所有的應用程序（如 flashers 或恢復程序）都可以加載。&lt;br /&gt;- 只兼容 Memory Stick Pro Duo。Memory Stick Duo（如 32MB 卡）不支持。&lt;br /&gt;- IDStorage 無法完全恢復，因為沒有已知的辦法能重新正確生成。&lt;br /&gt;- 強烈建議在做任何降級操作之前備份現有的 flash。&lt;br /&gt;- 在降級的最後，可能會出現 BSOD。這是正常顯現，標準降級程序也會出現類&lt;br /&gt; 似的情況。&lt;br /&gt;- 至今為止的所有硬件版本均支持。&lt;br /&gt;- 本發佈不包含任何 Sony 版權所有的內容。所需的 Sony 數據僅由 1.50 升&lt;br /&gt; 級程序生成得到。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;製作者名單&lt;/strong&gt;&lt;br /&gt;- 請不要修改或移除製作者名單... ;)&lt;br /&gt;- 所有工作由 Prometheus(C+D) 小組完成：&lt;/p&gt;&lt;p&gt;  Adrahil (VoidPointer)&lt;br /&gt; Booster&lt;br /&gt; Cswindle (Caretaker)&lt;br /&gt; Dark_AleX (Malyot)&lt;br /&gt; Ditlew&lt;br /&gt; Fanjita (FullerMonty)&lt;br /&gt; Joek2100 (CosmicOverSoul)&lt;br /&gt; Jim&lt;br /&gt; Mathieulh (WiseFellow)&lt;br /&gt; Nem (h1ckeyph0rce)&lt;br /&gt; Psp250&lt;br /&gt; Skylark&lt;br /&gt; TyRaNiD (bockscar)&lt;/p&gt;&lt;p&gt;- 感謝所有為 PSPSDK 作出貢獻的人，沒有它，什麼也不會變成可能。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-6486013534353442504?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/6486013534353442504/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=6486013534353442504' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/6486013534353442504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/6486013534353442504'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2009/01/pspparade-batterv15.html' title='PSP用parade battery降級v1.5方法'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-8306274262625880526</id><published>2009-01-06T20:07:00.000-08:00</published><updated>2009-01-06T20:09:40.065-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/硬體'/><title type='text'>PECL/LVDS介面電路</title><content type='html'>&lt;table style="width: 676px; height: 149px;" align="center"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F1.JPG" title="點擊在新窗口中察看大圖" target="_blank"&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F1.JPG" align="left" border="0" width="250" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖1：&lt;a href="http://www.eettaiwan.com/SEARCH/ART/PECL.HTM" target="_blank"&gt;PECL&lt;/a&gt;/LVPECL到&lt;a href="http://www.eettaiwan.com/SEARCH/ART/LVDS.HTM" target="_blank"&gt;LVDS&lt;/a&gt;的&lt;a href="http://www.eettaiwan.com/SEARCH/ART/%A4%B6%AD%B1.HTM" target="_blank"&gt;介面&lt;/a&gt;電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&lt;a href="http://www.eettaiwan.com/SEARCH/ART/%A7C%B9q%C0%A3%AEt%A4%C0%B0T%B8%B9.HTM" target="_blank"&gt;低電壓差分訊號&lt;/a&gt;(LVDS)在對訊號完整性、低抖動及共模特性要求較高的系統中得到了廣泛的應用。本文針對LVDS與其他幾種介面標準之間的連接，對幾種典型的LVDS介面電路進行了討論。 &lt;/p&gt;&lt;p&gt;如今對高速數據傳輸的需求正推動著介面技術向高速、串列、差分、低功耗以及點對點介面的方向發展，而低電壓差分訊號(LVDS)具備所有這些特性。Pericom半導體公司可提供多種LVDS驅動器、接收器以及時脈分配緩衝器晶片。 &lt;/p&gt;&lt;p&gt;本文將討論LVDS與正射極耦合邏輯(PECL)、低電壓正射極耦合邏輯(LVPECL)、電路模式邏輯(CML)、RS-422以及單端元件之間採用電阻網路的介面電路設計。&lt;/p&gt;&lt;table align="right"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F2.JPG" title="點擊在新窗口中察看大圖" target="_blank"&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F2.JPG" align="right" border="0" width="239" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖2：調整電路，R1＝(VR1＋R1a)&lt;br /&gt;，R2＝(VR2＋R2a)，R3＝(VR3＋R3a)。 &lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;因為各廠商所提供的驅動器與接收器的結構不一樣，所以本文提供的電路僅供設計時參考。設計者需要對電路進行驗證，並調節電路中的電阻和電容值以獲得最佳性能。 &lt;/p&gt;&lt;p&gt;&lt;b&gt;電阻分壓器的計算&lt;/b&gt; &lt;/p&gt;&lt;p&gt;表1列出了本文所採用的不同介面標準的工作電壓。為使PECL和LVPECL介面標準能與Pericom公司的LVDS元件進行連接，採用電阻分壓器在不同電壓之間切換。&lt;/p&gt;&lt;table align="left"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F3.JPG" align="left" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖3：PECL到LVDS的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;圖1所示的介面電路採用由電阻R1、R2和R3組成的電阻分壓器。R1、R2與R3的電阻值計算如下： &lt;/p&gt;&lt;p&gt;R1||(R2＋R3)＝Z &lt;/p&gt;&lt;p&gt;&lt;br /&gt;[(R2＋R3)/(R1＋R2＋R3)]＝Va/Vcc &lt;/p&gt;&lt;p&gt;&lt;br /&gt;R3/(R1＋R2＋R3)＝Vb/Vcc &lt;/p&gt;&lt;p&gt;其中： &lt;/p&gt;&lt;p&gt;&lt;br /&gt;Va為SEPC或LVPECL的偏置電壓Vos，分別為3.6V和2.0V； &lt;/p&gt;&lt;p&gt;&lt;br /&gt;Vb為LVDS的偏置電壓Vos，等於1.2V；&lt;/p&gt;&lt;table align="right"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F4.JPG" align="right" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖4：LVDS到PECL的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&lt;br /&gt;Z為線路阻抗，等於50Ω。 &lt;/p&gt;&lt;p&gt;Vb上的增益G為： &lt;/p&gt;&lt;p&gt;&lt;br /&gt;G＝R3/(R2＋R3) &lt;/p&gt;&lt;p&gt;Vb上的擺幅為： &lt;/p&gt;&lt;p&gt;&lt;br /&gt;Vbs＝Vas×G &lt;/p&gt;&lt;p&gt;其中：&lt;/p&gt;&lt;table align="left"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F5.JPG" align="left" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖5：LVPECL到LVDS的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&lt;br /&gt;Vas為Va上的擺幅； &lt;/p&gt;&lt;p&gt;&lt;br /&gt;Vbs為Vb上的擺幅。 &lt;/p&gt;&lt;p&gt;由於在計算中沒有考慮驅動器的輸出阻抗，所以在實際應用設計中，R1、R2及R3的電阻值與上述計算的結果不一樣。另外，不同廠家的驅動器的輸出結構和阻抗不一樣，因此R1、R2及R3的電阻值也是不同的。 &lt;/p&gt;&lt;p&gt;可以透過三種方法算出電阻值。 &lt;/p&gt;&lt;p&gt;1.經驗法&lt;/p&gt;&lt;table align="right"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F6.JPG" align="right" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖6：LVDS到LVPECL的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&lt;br /&gt;利用表2列出的電阻參考值，並根據後面介紹的方法2及方法3來調節這些值。介面設計者應透過測量Va和Vb上的偏置電壓Vos以及擺幅Vpp來驗證實際應用設計電路。 &lt;/p&gt;&lt;p&gt;2.模擬工具法 &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;從廠商獲得驅動器的IBIS模型，並針對R1、R2及R3的電阻值對介面電路進行模擬。如果IBIS模型和模擬工具都很精確，則電路模擬將提供準確的R1、R2及R3的電阻值，然後透過測量實際電路來驗證模擬得到的電阻值。 &lt;/p&gt;&lt;p&gt;3.實際調節法&lt;/p&gt;&lt;table align="left"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F7.JPG" align="left" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖7：採用二極體的LVDS到LVPECL的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;採用圖2所示的電路調節R1、R2及R3的電阻值。電阻R1a、R2a及R3a用來限制調節範圍，以避免出現過載電流。當調節電路並用示波器監視Va與Vb上的訊號時，調節VR1、VR2與VR3： &lt;/p&gt;&lt;p&gt;a. 對於Pericom公司的LVDS接收器，Vb上的Vos(在擺幅範圍中間的平均電壓)應介於0.8V－1.6V之間。有關Va上的Vos，請查閱驅動器參數。 &lt;/p&gt;&lt;p&gt;b. 對於Pericom公司的接收器，Vb上的擺動範圍應介於350mV－550mV之間。有關Va上的擺幅，請參見驅動器規範，Va上的擺幅可能低於驅動器規範以便滿足Vb上的擺幅要求。&lt;/p&gt;&lt;table align="right"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F8.JPG" align="right" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖8：CML到LVDS的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;c. 電路調節完以後，再測量VR1與R1a，得到R1的電阻值；測量VR2與R2a，得到R2的電阻值；測量VR3與R3a，得到R3的電阻值。 &lt;/p&gt;&lt;p&gt;d. 用較低頻率的訊號對電路進行調節會更加簡單，頻率最好介於100kHz-10MHz之間，但請確認電路是否在正常頻率下工作，如果需要的話可再次調節。 &lt;/p&gt;&lt;p&gt;&lt;b&gt;介面電路的限制&lt;/b&gt;&lt;/p&gt;&lt;table align="left"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F9.JPG" align="left" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖9：LVDS到CML的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;由於介面電路增加了的額外電容與電阻網路，因此介面電路的最高工作頻率將低於元件手冊上提供的最高頻率。驅動器與接收器之間的走線長度也有限制，走線長度取決於頻率，當頻率為66MHz時，估計最大走線長度為14英吋，頻率為320MHz時則為2英吋。 &lt;/p&gt;&lt;p&gt;走線長度是一個實際問題且取決於實際設計。為減少寄生電容、電感及訊號反射以獲得更高性能，介面電路中元件之間的走線應盡量短，越短越好。介面電路使用的電容、電阻以及二極體必須為短引腳的高速元件，而且最好採用晶片型封裝。 &lt;/p&gt;&lt;p&gt;&lt;b&gt;參考介面電路&lt;/b&gt; &lt;/p&gt;&lt;p&gt;圖3至圖12給出了LVDS與PECL、LVPECL、CML、RS-422及單端元件之間的介面電路，它們的調節方法以及電路限制如前所述。 &lt;/p&gt;&lt;p&gt;1. LVDS至PECL&lt;/p&gt;&lt;table align="right"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F10.JPG" align="right" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖10：RS-422到LVDS的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;在圖4所示的LVDS到PECL的介面電路裡，PECL接收器沒有內部上拉電阻。該電路中的電阻值僅適用於Pericom公司的 LVDS驅動器。由於採用交流耦合，這個介面只能通過交流訊號，因此從驅動器傳輸到接收器的訊號必須適合交流耦合。當電容C1與C2為0.1uf時，任何 訊號狀態轉換(由高至低或由低至高)之間的最大時間間隔為500ns。 &lt;/p&gt;&lt;p&gt;2. LVDS到LVPECL&lt;/p&gt;&lt;table align="left"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F11.JPG" align="left" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖11：單端訊號到LVDS的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;在圖6所示的LVDS到LVPECL的介面電路裡，電阻值也僅適用於Pericom公司的LVDS驅動器，這裡的LVPECL接收器沒有內部上拉電阻。 &lt;/p&gt;&lt;p&gt;圖7中，二極體D1、D2、D3和D4在Va與Vb之間產生0.7V的電壓差，且其擺幅衰減低於圖6電路中的擺幅衰減。這個 電路應採用正向壓降為0.7V的高速二極體，晶片型二極體最好。電路中的電阻值適用於Pericom公司的LVDS驅動器，LVPECL接收器沒有上拉電 阻。 &lt;/p&gt;&lt;p&gt;3. CML到LVDS&lt;/p&gt;&lt;table align="right"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7F12.JPG" align="right" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;圖12：5V單端訊號到LVDS的介面電路。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;圖8介面電路採用交流耦合，只能通過交流訊號，因此從驅動器傳輸到接收器的訊號必須適合交流耦合。當電容C1與C2為0.1uf時，任何訊號狀態轉換(由高至低或由低至高)之間的最大時間間隔為500ns。 &lt;/p&gt;&lt;p&gt;圖9電路中的電阻值適用於Pericom公司的LVDS驅動器，CML接收器帶有50Ω的內部上拉電阻。由於採用交流耦合， 故它僅能通過交流訊號，因此從驅動器傳輸至接收器的訊號必須適合交流耦合。當電容C1與C2值為0.1uf時，任何訊號狀態轉換(由高至低或由低至高)之 間的最大時間間隔為500ns。&lt;/p&gt;&lt;table align="left"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7T1.JPG" align="left" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;表1：LVDS、PECL、LVPECL、&lt;br /&gt;CML和RS-422介面的電壓規範。&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;4. 單端訊號到LVDS &lt;/p&gt;&lt;p&gt;當單端CMOS驅動器與Pericom公司的LVDS接收器連接時，可採用圖11中的電路以及表3中的參數，同時使由R_out和R_termination構成的輸出阻抗與50Ω的走線阻抗相匹配，即： &lt;/p&gt;&lt;p&gt;R_out＋R_termination＝Z＝50Ω&lt;/p&gt;&lt;table align="right"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7T2.JPG" align="right" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;表2：R1、R2和R3的參考值。 &lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;例如，如果驅動器的輸出阻抗為20Ω，則應該採用30Ω的R_termination，於是有： &lt;/p&gt;&lt;p&gt;20Ω＋30Ω＝50Ω &lt;/p&gt;&lt;p&gt;在圖12中，根據Vb上的訊號品質，R_termination的阻值介於0－22Ω之間。如果Vb上有過衝和下衝，則增加R_termination的阻值；如果Vb上的訊號邊沿有衰減，則減小R_termination的阻值。 &lt;/p&gt;&lt;p&gt;&lt;b&gt;本文小結&lt;/b&gt;&lt;/p&gt;&lt;table align="left"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://www.eettaiwan.com/ARTICLES/2005MAY/B/0505B_DC_S7T3.JPG" align="left" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="maintext"&gt;&lt;p&gt;&lt;i&gt;表3：適合Pericom公司接收器的R1、R2和Va值。 &lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-8306274262625880526?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/8306274262625880526/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=8306274262625880526' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/8306274262625880526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/8306274262625880526'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2009/01/pecllvds.html' title='PECL/LVDS介面電路'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-6483991047756390977</id><published>2008-12-29T05:01:00.001-08:00</published><updated>2008-12-29T05:01:55.182-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/其他'/><title type='text'>轉貼：XP 的終端機多人同時登入</title><content type='html'>&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;h4 class="beTitle" id="subjcns!E0070FB8ECF9015F!1425"&gt;XP 的終端機也能多人同時登入！&lt;/h4&gt;&lt;div id="msgcns!E0070FB8ECF9015F!1425" class="bvMsg"&gt;&lt;p&gt;這是篇轉載來的文章，如果作者看到覺得有侵害到您的權益，請再告訴 Heresy。 &lt;/p&gt;&lt;hr /&gt;  &lt;p&gt; &lt;/p&gt;&lt;p&gt;XP Pro 的遠端桌面只允許一個人連線，當其他使用者使用遠端桌面連線到 XP Pro 時，本機使用者會被強制登出。  &lt;/p&gt;&lt;p&gt;只要完成下列步驟，就可以解除這個限制，經實測確實可行（測試機器為 XP Pro SP2 Vol 版本，本機主控台一個工作階段加上兩部電腦遠端登入）。  &lt;/p&gt;&lt;ol&gt;&lt;li&gt;將 Windows 啟動在安全模式。  &lt;/li&gt;&lt;li&gt;按一下 [控制台] 中的 [系統]，取消選取 [遠端] 索引標籤中的 [允許使用者允端連線到這部電腦]，然後按一下 [確定]。  &lt;/li&gt;&lt;li&gt;開啟 [控制台] - [系統管理工具] - [服務]，將 Terminal Services 服務停用，然後按一下 [確定]。  &lt;/li&gt;&lt;li&gt;瀏覽到 C:\windows\system32\dllcache 目錄，將 termsrv.dll 檔案改成別的名稱（例如 termsrv.original）。  &lt;/li&gt;&lt;li&gt;從 &lt;a href="http://www.orbitfiles.com/download/id20947665"&gt;http://www.orbitfiles.com/download/id20947665&lt;/a&gt; 下載無連線數目限制的 termsrv.dll，然後將它複製到 C:\windows\system32\dllcache 目錄。  &lt;/li&gt;&lt;li&gt;瀏覽到 C:\windows\system32 目錄，重複步驟 4 與步驟 5 (將 termserv.dll 改成其他名稱，然後將剛下載的檔案複製到此目錄。  &lt;/li&gt;&lt;li&gt;開 啟 [登錄編輯程式]，找到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Licensing Core 機碼。新增一個名為 EnableConcurrentSessions 的 DWORD 項目，將其值設定為 1，然後關閉 [登錄編輯程式]。 &lt;/li&gt;&lt;li&gt;按一下 [ 開始] - [執行]，輸入 gpedit.msc，然後按一下 ENTER。開啟 [電腦設定] - [系統管理範本] - [Windows 元件] - [終端機服務]，按兩下 [限制連線數目]，選擇 [已啟用]，然後在 [可允許的 TS 最大連線數目] 中設定想要的最大連線數目。 &lt;/li&gt;&lt;li&gt;重新啟動 Windows 在正常模式。  &lt;/li&gt;&lt;li&gt;按一下 [控制台] 中的 [系統]，選取 [遠端] 索引標籤中的 [允許使用者允端連線到這部電腦]，然後按一下 [確定]。  &lt;/li&gt;&lt;li&gt;開啟 [控制台] - [系統管理工具] - [服務]，將 Terminal Services 服務啟動，然後按一下 [確定]。  &lt;/li&gt;&lt;li&gt;重新啟動 Windows。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;注意：  &lt;/p&gt;&lt;ol&gt;&lt;li&gt;您必須為使用者建立帳戶並將他加入 Remote Desktop User 群組，該使用者才能連線。  &lt;/li&gt;&lt;li&gt;您可能必須啟用「快速使用者切換」與「歡迎畫面」，按一下 [開始] - [控制台] - [使用者帳戶] - [變更使用者登入或登出的方式] 以啟用上述兩個功能。  &lt;/li&gt;&lt;li&gt;此解決方案可能不適合已加入網域的電腦，因為網域群組原則可能會覆寫本機群組原則。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;問答集：  &lt;/p&gt;&lt;ol&gt;&lt;li&gt;問：&lt;a href="http://www.orbitfiles.com/download/id20947665"&gt;http://www.orbitfiles.com/download/id20947665&lt;/a&gt; 這檔案哪來的？&lt;br /&gt;答：據聞取自 XP SP2 RC1，termsrv.dll 版號 5.1.2600.2055。  &lt;/li&gt;&lt;li&gt;問：在開啟 [自動更新] 的情況下，這個檔案會被更新為最新的版本嗎？&lt;br /&gt;答：不清楚，個人並不使用 [自動更新]。照理說如果這個檔案沒有被發現有弱點，MS 應該不會釋出更新。  &lt;/li&gt;&lt;li&gt;問：這個方式適用於 XP Home 版本嗎？&lt;br /&gt;答：不清楚，個人沒有 Home 版本，只有在 XP Pro 版本測試過可行。或許您可以試試然後告訴大家結果。  &lt;/li&gt;&lt;li&gt;問：會不會有任何安全上的問題？&lt;br /&gt;答：不清楚，請自行負擔所有風險。&lt;/li&gt;&lt;/ol&gt; &lt;hr /&gt;  &lt;p&gt;此外： &lt;/p&gt;&lt;p&gt;有人把步驟寫成批次檔，install 一下就好了 &lt;a href="http://concurrentremotesessions.netfirms.com/Concurrent_Remote_sessions_SP2.zip"&gt;http://concurrentremotesessions.netfirms.com/Concurrent_Remote_sessions_SP2.zip&lt;/a&gt;&lt;br /&gt;裡面的批次檔寫死成 c:\windows, 若 windows xp 不是裝在 c:, 需自行修改其實用 %windir% 就好了&lt;/p&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-6483991047756390977?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/6483991047756390977/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=6483991047756390977' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/6483991047756390977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/6483991047756390977'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/12/xp.html' title='轉貼：XP 的終端機多人同時登入'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-5921706341934724264</id><published>2008-10-31T06:48:00.000-07:00</published><updated>2008-10-31T06:49:12.565-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/其他'/><title type='text'>[轉載]如何成為一位傑出的工程師</title><content type='html'>&lt;p&gt;&lt;b&gt;&lt;span style="color: red;"&gt;&lt;/span&gt;&lt;/b&gt;如何成為一位傑出的工程師&lt;br /&gt;&lt;a href="http://vlsicad.ucsd.edu/Research/Advice/star_engineer.pdf"&gt;How to be a Star Engineer&lt;/a&gt;&lt;br /&gt;Robert E. Kelley, Carnegie Mellon University&lt;br /&gt;(Robert E. Kelley, "How to be a star engineer," IEEE Spectrum, pp. 51-58, Oct. 1999.)&lt;br /&gt;翻譯：馬仕毅&lt;br /&gt;&lt;/p&gt;&lt;p&gt;在1985 年，我被問了一些問題,從那時起,我就開始找尋真正的答案。提出問題的是貝爾實驗室(那是仍然是AT&amp;amp;T的一部分，現在屬於 Lucent Technologies Inc.)。貝爾實驗室由全世界最好的大學中聘用了最優秀，最聰明的畢業生,然而, 最後只有少數的人真正發揮他們的潛力而成為卓越的工程師。大部分的新進人員發展成可以穩定地完成任務的執行者，生產力並沒有特別突出，無法幫助貝爾實驗室 在提昇AT&amp;amp;T的市場競爭力方面，做出顯著的貢獻。&lt;/p&gt; &lt;p&gt;貝爾實驗室想要知道的是：傑出的工程師和普通的工程師到底有什麼不同？傑出與否是由天份來決定？還是可以經由學習得來？可不可以設計一套提昇生產力的計畫來幫助表現平平的員工成為傑出的人才？&lt;/p&gt; &lt;p&gt;不 只有公司才會尋求這些問題的答案。由1985年開始，幾乎所有我遇到的工程師都希望能夠增加自己的生產力。他們覺得自己也可以出類拔萃，他們不喜 歡被同事的光芒所掩蓋。因此他們不斷地努力求進步。在現今的職場中，資源越來越少,工作的要求卻越來越多。全球化的競爭，購併風氣,企業裁員使得每位員工 所承擔的責任越來越重大，而可利用的資源卻比以前少。環顧你的四周，和五年前比較，那位不是比以前工作更努力，工時更長？誰不是待完成的工作一堆，好多的 電話和電子郵件還沒回？大家都在暗自擔心，如果不能再提高生產力，下一個被裁員的會不會是自己？誰不希望能夠重新掌握自己的生活-在工作和個人生活中取得 一個更好的平衡點？&lt;strong&gt;每個人都聽過：更聰明地工作(work smarter)，只是似乎沒人知道那是什麼意思&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;我 和我的同事從那時起就開始研究公司和個人生產力的問題。來自貝爾實驗室，3M，及惠普公司總計超過一千位工程師在這個研究的過程中，同時扮演了研 究夥伴及受試者的角色。為了瞭解傑出工程師的秘密，我們使用了問卷調查，直接觀察，工作日記，焦點團隊(focus groups)，以及面試等方法來收集資料。並在適當的時候使用統計分析，內容分析(content analysis)，及反覆的模型建立(iterative model building)等方法。&lt;/p&gt; &lt;p&gt;許多其他的公司也都參與了這個過 程，包含了以電機工程師為重心的Analog Devices, Fore Systems, Air Touch，以及一些包含其他領域工程師的公司如Shell Oil, Kimberly Clark等。這些公司採用了我們的生產力提昇計畫。有效地將表現普通的員工轉換成傑出的工程師，而在這個過程中，也讓我們對於產生傑出表現的關鍵因素有 了更多的了解。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;通往傑出之路 &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Lai及Henry在進入貝爾實驗室時，兩人的背景近 似。都是由頂尖的大學畢業，平均成績3.8(GPA)。都曾經在電腦公司做過暑期工讀，而且都 獲得教授的全力推薦。然而，在剛進公司的前六個月，兩人採取了截然不同的態度來面對公司指派的工作。上午的時間，他們需要上有關電話技術以及貝爾實驗室工 作流程的課。下午的時間則參與一些暖身計畫(break-in projects)，這是一些需要完成的次要工作，即使是做得很差也不至於對重要的計畫造成影響。&lt;/p&gt; &lt;p&gt;Henry像在寫畢業論文或是準備考試似的將自己關在辦公室中。他收集了許多的技術文件以深入了解最新的技術進展，只有在上廁所或是參加必要的會議時才會離開辦公室。他記得當時的想法是『最重要的事情是：我是否可以證明給我的同事看，在技術上我真的很行』&lt;/p&gt; &lt;p&gt;Lai 每個下午安排的三個小時的時間來完成指派的工作以及增進技術上的技能。一有多出來的時間，她會向其他的同事自我介紹，同時了解一下他們正在進 行的計畫。如果有同事需要幫忙或是時程的壓力很大，她會自告奮勇要幫忙。雖然她對新的工作環境文化不熟，她的同事們還是覺得很窩心。特別是這些本來不是她 的問題。&lt;/p&gt; &lt;p&gt;有一天下午，有一位同事正在和一個困難的程式奮戰，而整個軟體計畫的時程只剩一週了。Lai以前在修一門高等課程時學過一個新的 程式工具，她覺得應 該可以應付這個程式，所以她主動提出要幫忙寫這個程式，這樣她的同事就可以專心應付更大的計畫。另一次，有一些複雜的軟體工具需要安裝在每個人的PC上。 依照以前的作法，是由每個人自己在電腦上安裝，有問題自己解決。Lai在以前暑期工讀的時候也曾遇過類似的狀況，她覺得由一個人來安裝這個軟體到所有的電 腦上比較合理。因此她主動建議由她來做。但是這個安裝的動作比想像中要困難，總共需要兩週的時間。比她原先估計的四天要多出很多。她原本可以放棄這個建 議，但是她仍然將這個工作實行完成。雖然她有好幾天必須提早到公司並且加班到很晚，才不會影響到白天的上課及計畫的進度。&lt;/p&gt; &lt;p&gt;六個月之後，Henry和Lai都完成了他們的技術課程以及第一個任務。他們的計畫執行成效都被評估為良好而且具有技術上的競爭力。實際上，Henry的計畫成果在技術上可能要比Lai來的高明一些。&lt;/p&gt; &lt;p&gt;然而在同事之間的認同度方面，Henry顯然比較不足。雖然大家都覺得他還好相處，同事們還是認為他比較像獨行俠。對於技術的部份相當熟練，但是未必能將他的技能和其他的同事分享。他的行事態度還是和在學校時一樣，只在乎個別的表現。&lt;/p&gt; &lt;p&gt;在另一方面，Lai給別人的印象就比較主動積極。她肯主動發掘並解決問題，即使那並不在她的責任範圍內。同事們都覺得她好像進入實驗室不只六個月了。當然，經理們也注意到了Lai具有成為傑出工程師的特質。已經開始考慮要讓她參與更重要的計畫了。&lt;/p&gt; &lt;p&gt;大 部分的人(如Henry)都對於傑出工作能力的成因有自己的理論，然而，大多數都錯得很離譜。過去14年來，我們對於傑出工程師的成因，有許多令 人吃驚的發現，也打破了許多很普遍的迷思。我們的第一個發現是：老闆們和同事們眼中的傑出人才往往差異很大。我們首先請經理人列出他們心目中的傑出人選， 然後再建議他們篩選這些人選，請他們想一想如果他們有很重要的計畫要執行，或是重大計畫有什麼緊急狀況，需要特種部隊來解決問題，或是自己要出來創業，需 要聘請一些高手時，誰是最佳人選。當我們將這張表拿給表現傑出的工程師們看時，他們往往對老闆們的選擇嗤之以鼻。『Joe怎麼可能會入選？他已經好幾年沒 做什麼事了。還有，Maria 怎麼沒在上面？每個人有問題卡住了或是需要新點子時都會去找她。』&lt;/p&gt; &lt;p&gt;這個反應的差異讓我們停下來重新思索。我們往後退了一個步驟，重新要求經理人以及工程師中的高手分別列出那些人的績效比其他的同事高出許多。特別是做事方式讓其他人佩服的。我們想要排除那些不擇手段獲取績效的人，往往他們對組織造成的傷害大到可以抵銷他們所有的貢獻。&lt;/p&gt; &lt;p&gt;這個步驟的結果是：兩方所提出來的人選當中，只有大約百分之五十的人是重複的。優秀的工程師和經理人對於誰的表現比較好，大約有一半的機會是看法不一致的。&lt;/p&gt; &lt;p&gt;在 我們最早在貝爾實驗室的研究中，我們對受試者做進一步的挑選。只有在經理人及同事們眼中都表現傑出的工程師才會成為我們的研究對象。(在之後研究 3M公司時，我們把客戶的看法也考慮進去)。我們同時也考慮了他們所獲得的獎項，榮譽，及考績獎金的數目等。另外，專利及發表文章的數量也會列入考慮。這 些條件都滿足的傑出工程師就構成我們研究的對象，由其中分析傑出表現的成因。&lt;/p&gt; &lt;p&gt;為了要分出表現平平的表現優異的員工的主要差異，我們請教了高階主管，中階主管，工程師，以及其他研究者的看法。由這些結果中，我們累積了45個主管們及工程師們都覺得會影響傑出表現的主要因素。大致上可以分為四大類：&lt;/p&gt; &lt;p&gt;·  一、&lt;strong&gt;認知類的因素&lt;/strong&gt;：比較高的智商，邏輯推理能力，及創意。&lt;/p&gt; &lt;p&gt;·  二、&lt;strong&gt;個性因素&lt;/strong&gt;：自信，野心，勇氣，以及是否相信可以控制自己的命運。&lt;/p&gt; &lt;p&gt;·  三、&lt;strong&gt;社交因素&lt;/strong&gt;：人際關係，領導能力。&lt;/p&gt; &lt;p&gt;·  四、&lt;strong&gt;工作及組織因素&lt;/strong&gt;：與主管的關係，工作成就感，對於薪資及獎金的態度。&lt;/p&gt; &lt;p&gt;接下來，要找出這45個因素中那些是影響傑出表現的重要因素。我們對數百位表現傑出及表現普通的工程師做了為期兩天的測試。我們同時也做了資料的蒐集及分析，建立詳細的個案歷史資料，和員工及僱用他們的主管面談。同時也請他們提供自傳及個人的檔案資料。&lt;/p&gt; &lt;p&gt;令 人困惑的是，經過兩年的研究，我們的資料顯示不論是認知因素，個性因素，社交因素，或是工作及組織因素都無法作為分辨出傑出表現的有效因素。對於 上面列的所有傳統因素，無論是單獨或是合併分析，答案都是一樣：無法藉以分辨出普通工程師和傑出工程師。我們用了十幾種比較資料的方式，將電腦分析應用到 極限，然而，每次的執行結果都讓我們當時覺得：我們的分析方法一定是有什麼嚴重的錯誤。我們找不到任何一個可以分辨一個人是否會有傑出表現的因素。&lt;/p&gt; &lt;p&gt;難道是另有一些關鍵因素我們還沒有發現？難道我們原先以為的主要因素：認知因素，個性因素，社交因素，工作及組織因素完全與傑出表現無關？&lt;/p&gt; &lt;p&gt;我 們研究結果的長期效應是打破了一般人對於傑出表現的迷思。而事實上，在我們之後的研究發現：其他的因素也其影響力。只是大部分的工程師在進入職場 時，早已具有足夠的潛力可以表現得卓越非凡，然而最後卻成就普通。成就傑出表現的原因並不在他們擁有什麼，而在於他們如何應用他們所擁有的特質。傑出表現 之謎其實在於如何將他們的天分轉換成生產力：就好像將位能轉換成動能一樣。我們的結論是：&lt;strong&gt;傑出的表現是努力得來的，與天份無關。(Stars are made, not born.) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt; 九個工作策略 &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;好 了，如果你是一個希望能夠提高生產力，增加自己智慧資產的工程師。你該如何做才能讓別人覺得你表現傑出呢？在我們這個研究之前，這個答案並不存 在。無論是在學校或是在職場中，沒有任何地方在教培養傑出表現的工作策略。大多數的人藉由試誤法來驗證自己的想法。然而，許多計術上極有競爭力的工程師因 為在這個過程中犯了太多錯誤，使得他們的整體表現僅僅比平均稍高一些而已。例如，他們可能沒有採取主動積極的態度，或者是他們在對整個組織重要性不高的方 面主動積極。&lt;/p&gt; &lt;p&gt;我們發現，改變你做事的方法以及和別人共事的方法是有必要的。表現傑出的人事實上做事的方法和其他的人有相當的差異。他們將他們的工作策略融合到每天的表現中，產生一個前後一致的行為準則。任何一位具有足夠聰明和動機的工程師都可以獲得卓越表現的能力。&lt;/p&gt; &lt;p&gt;盡管如此，這種生產力的發揮並不是像大爆炸一樣的釋放出來。也沒有魔法藥丸或是神奇子彈可以讓你瞬間出類拔萃。而是藉由九個互相結合在一起的工作策略為基礎發展起來的。以下依照重要性排列，分別介紹這九種工作策略。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. 閃亮的軌跡(Blazing trails) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;你對於之前提到的Lai和Henry的看法是什麼？你是否覺得Henry被低估了因為他只強調技術上的競爭力並不公平？或者Lai受賞識只因她會閒聊？&lt;/p&gt; &lt;p&gt;一 般的員工，如Henry，腦海中的主動積極是：想出一些新的想法可以讓他們的工作做得更好，或是在公司主動幫忙一些額外的事情，例如規劃年度野餐 或是號召同仁去捐血。實際上，Henry覺得他自己很主動，『我收集了最新的技術文件並學習了最新的軟體工具，因而我可以將我的指派工作做得極好。沒有人 叫我做這些。』Henry這樣告訴我。&lt;/p&gt; &lt;p&gt;Lai很清楚而Henry並不了解的一個關鍵是：只有特定的行為才能讓別人覺得你主動積極。主動積極的真正意涵是：&lt;/p&gt; &lt;p&gt;·  &lt;strong&gt;主動追求超過自己職權範圍的更大責任&lt;/strong&gt;(例如Lai主動幫忙安裝新的軟體工具)。&lt;strong&gt;同時仍然能夠完成自己的主要任務&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;·  &lt;strong&gt;能夠額外付出心力來幫助其他同事或是團隊&lt;/strong&gt;，就像Lai主動幫助她的同事應付難纏的程式。&lt;/p&gt; &lt;p&gt;·&lt;strong&gt; 當有重要的任務出現在每個人職權中間的灰色地帶時，能夠主動承擔起責任，並且將任務完美達成&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;對於認定的目標或是計畫，不屈不撓地堅持直到成功地執行完畢。就像Lai在幫忙安裝軟體時以加班的方式完成原先的構想。&lt;/p&gt; &lt;p&gt;在一般人的印象中，唯一值得主動去做的事是發明一個商業上成功的新產品，比如說發明物件導向的Java語言。如果你花了許多心力，卻無法在華爾街日報頭版上刊登一篇讚美重大貢獻的文章，那你主動的努力就白費了。&lt;/p&gt; &lt;p&gt;然 而，在我們的研究中，傑出的工程師都堅信：雖然他們非常期望夠主動積極地做出巨大的貢獻，日常中的小貢獻，日復一日地累積起來，也可能造成同樣的 影響力。不只這樣，他們發現通常一個重大的發現是在一連串較小的努力之後，慢慢形成的。如果你自己的工作態度是不注重在小地方採取主動的態度，則你所累積 的貢獻會逐漸乾涸，而重大的突破永遠都沒有機會發生。例如，Lai主動幫助同事處理一個繁瑣的程式，可能可以讓她的同事獲得一個喘息的空間，而這正是在工 作上要產生有意義的突破所需要的條件。&lt;/p&gt; &lt;p&gt;傑出的工程師同時也相信，你可以主動做出貢獻的程度會和你的經驗直接相關。Lai在還是新進人員 時，大家並不期望她承擔太大的責任，但是她主動對周 遭的人做出一些小貢獻為她的同事帶來一些意外的驚喜。同時也很快地讓其他人認同她是一位有生產力的工程師。當她越來越有經驗之後，大家才會開始期望她能夠 主動地承擔更高難度，風險更高的任務。&lt;/p&gt; &lt;p&gt;我們對Lai, Henry及其他數百位其他工程師的觀察發現，對於任何一個有競爭力的專業工作者團隊，新進人員必須展現主動積極的精神。這樣的態度不只會讓主管感到滿 意，更重要的是，你的同事和客戶也會因此而欣賞你的表現。同事們期望中的工作夥伴不會將自己侷限在職務說明書中所列舉的任務中。他們希望他們的同事可以像 Lai一樣願意做超過自己職權範圍以外的任務。因為他們知道，如果一個新進的人員的工作份量比自己少，自己就要承擔更多的責任。他們需要能夠延伸自己責任 範圍的工作夥伴，無論是和同事更能搭配，提供客戶更好的服務，或是更能應付市場的迅速改變。&lt;/p&gt; &lt;p&gt;不只是主管和同事，客戶們也會期望他們所接觸的員工具有這些特質。如果一個新進人員沒有辦法滿足這些期望，他們可能會和Henry一樣，被歸類為有能力但是生產力不足的員工，無法對整個團隊做出正面的貢獻。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2. 知道該問誰(Knowing who knows) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一般的員工對於建立人際關係網路的想法僅止於有管道可以得知最新的辦公室八卦，或者是和自己領域中的人及獵人頭公司的主管保持聯絡，以便於日後可以轉換更好的工作。&lt;/p&gt; &lt;p&gt;傑 出的工程師除了上述的管道之外，另外維持了一種更重要的人際關係網路。因為他們了解，目前社會資訊過載的程度已經使得很少人具備完成工作所需的所 有資訊。他們可能具備50-80%的知識，但是除非有辦法能夠將剩下的部份補起來，否則他們的工作就無法順利完成。有效的人際聯繫正是他們補足資訊不足的 方法。&lt;/p&gt; &lt;p&gt;善於利用這個聯繫的人很清楚必須事先和各領域的專家建立可靠的雙向聯絡管道。這個聯繫網路中的專家們可以藉由彼此的幫助完成手邊的重要任務。建立這個網路的主要的目的，是希望盡可能地降低本身的知識不足以勝任新工作的機會。&lt;/p&gt; &lt;p&gt;有效的人際網路和一般人的人際關係有兩個最大的不同點：一是有效的人際網路包含了對的人，二是獲得回應的速度快。&lt;/p&gt; &lt;p&gt;他們所認識的專家可以第一時間就提供正確的答案。一般人則比較常得到錯誤的資訊，通常是因為問錯人，或是知道答案的專家並不在他的人際關係網路中。他們可能因而被誤導，或是繼續盲目摸索。&lt;/p&gt; &lt;p&gt;反應迅速的的人際網路可以使得優秀的工程師迅速的獲得自己所缺乏的資訊，而能夠比其他的人更早繼續進行工作。假設他們花了半天的時間來來問到他們所要得答案，其他的人大概要花一兩天的時間，而且通常得到的還是錯誤的資訊。長時間下來，累積的差異相當可觀。&lt;/p&gt; &lt;p&gt;優秀的工程師因為建立了更有效而且更迅速的網路，生產力得以進一步的提昇而能夠超越普通的工程師。即使是具有相同的天份，光靠自己總是有所不足。&lt;/p&gt; &lt;p&gt;Andersen Consulting, 一家國際性的顧問公司，指派公司的一位資訊技術顧問 Claudio 來撰寫一份時限很緊的合約提案。這是一份五十萬美元的合約，內容是提供生物技術公司所使用生物化驗程序的資訊技術支援。&lt;/p&gt; &lt;p&gt;Claudio記得他有一個大學同學現在在生物技術領域中最有名的公司Genentech Inc.上班，因此與她聯絡，而她則介紹了一位專攻生物化驗程序的同事給Claudio。僅僅用了兩通電話，他就獲得了完成他的合約提案所需要的資訊。&lt;/p&gt; &lt;p&gt;發 生在Claudio的另一位同事，Newt身上的狀況就不同了。和Claudio一樣，Newt也需要相同的資訊。但是Newt並沒有運用自己的 人際網路，而採用了公司的建議，將他的問題貼在公司內部的電子留言板上。第二天，他發現電腦內有40個回應等著他去處理。這些回應的答案有許多是彼此互相 牴觸的，但是由於他並不認識這些提供回應的人，無法判斷其中回答的品質。他只好一個一個的去了解和確認這40個回應的內容。&lt;/p&gt; &lt;p&gt;因此，當Newt還在為他獲得過多的資訊而傷腦筋時，Claudio已經利用他有效率的人際網路將兩人的差距越拉越大。&lt;/p&gt; &lt;p&gt;針對資訊獲得的問題，目前高級主管們普遍的作法是以改進公司內部電腦網路作為解決方案。主管們花了數百萬美元的經費在新增電腦硬體及軟體上面，相信像Newt這樣的員工可以用email解決他們的困境。&lt;/p&gt; &lt;p&gt;但是成功的人際聯繫通常建立在一對一的直接溝通上，比較不人性的電腦網路廣播往往效果不佳。傑出的工程師會花許多精神在建立，維繫，及運用由一群專家們彼此互通有無所組成的高效率人際關係網路。和其中有沒有使用高科技沒有直接的關係。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;3. 主動的自我管理(Proactive self-management) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一般人相信自我管理的意義在於對於時間及計畫的控制。如果他們的工作可以在原訂的時程，預算，及規格之內完成，則他們的自我管理一定沒有問題。&lt;/p&gt; &lt;p&gt;傑 出的工程師們知道主動自我管理的真正內涵決不只是時程及計畫管理。這兩項是每個員工都應該做到，而且是公司付錢請他們完成的。傑出的工程師的工作 策略在於主動地創造機會，影響工作上的決策，在工作上表現得極端優異，並且開創自己事業發展的方向。這樣的態度可以使他們加速累積工作經驗和才能，使得他 們在公司中的價值增加。&lt;/p&gt; &lt;p&gt;Elena在一家提供汽車工業先進陶瓷材料的公司從事研發的工作。她向公司提出出差申請，希望能夠去參加一個生產 力及品質的研討會。由於這個研討會 的內容和她的工作沒有直接相關，而且出差預算已經快用完，她的上司並不同意。Elena並沒有因為這個決定而打消念頭，因為她相信參加這個研討會會使得她 在公司中更有價值。她用了自己的假期去參加這個研討會，並且自付旅費。&lt;/p&gt; &lt;p&gt;在會中，她發現歐洲正在發展一個新的品質標準ISO 9000。這個標準建立了一些投標要求，目的在確保原料，產品，及生產程序的更高品質，使得歐洲的公司在全球市場中更具競爭力。如果像她公司這類提供原料的公司無法滿足這些要求，將無法參與歐洲的標案。&lt;/p&gt; &lt;p&gt;回來之後，她變得更活躍。她利用自己的時間研究ISO 9000的要求，並且利用午餐會議的時間向她的工作團隊解釋。很快的，她的同事們也開始重視這個議題，並且試著說服他們的上司提早準備歐洲的ISO 9000投標要求對於公司將有很大的幫助。&lt;/p&gt; &lt;p&gt;高 階的主管們比較難接受他們的觀點。他們懷疑歐洲會形成制定標準的共識，更別說是強制執行新的標準了。然而，Elena不斷嘗試讓主管們了解，她會 寄一些文章或是她寫的備忘錄給他們，提醒他們第一家符合這個標準的好處。最後，最高主管們看到了一些實質的好處，因此決定採納這個想法。現在，歐洲已經是 他們公司的最大客戶，同時，品質的提昇也對他們的美國市場有幫助。&lt;/p&gt; &lt;p&gt;Elena的自我管理使得公司經營得更成功。即使她的主管並不支持，她 仍主動積極地提昇自己的價值。同時，她也看到了提昇公司價值的機會。最 後，Elena的作法強調了各個工作策略是互相結合的。她的自我管理同時包含了主動積極-有意願做超過她的職務範圍，甚至超過她的上司，而達成一個所有人 都受惠的目標。而能完成這些的關鍵在於：她不輕易放棄。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;4. 掌握全局(Getting the big picture) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一般人都有目光短淺的問題。他們只由自己的角度看世界，並且將自己侷限在相同的觀點。&lt;/p&gt; &lt;p&gt;傑出工程師反而時常跳脫自己的角度而以許多不同的觀點來看事情。『我的客戶會怎麼想？我的競爭對手的想法是什麼？我的同事呢？我的上司和公司的股東又在想什麼？』由於他們可以用不同的視野來衡量事情的重要性，因此他們能對產品做出改良，或是對問題發展出更完善的解決方案。&lt;/p&gt; &lt;p&gt;傑 出工程師的觀點是由累積足夠的經驗而發展出來的判斷模式。Sarah在她獲得電腦科學的碩士學位之後在矽谷找了一個軟體開發的工作。在求學以及工 作的期間，她用一本筆記本來紀錄她對時常發生的問題及解決方式的觀察。每天晚上，她會仔細閱讀她的筆記本，像偵探一樣尋找問題的模式及其中的線索。&lt;/p&gt; &lt;p&gt;依Sarah 的實務和經驗，她和其他的新進人員一樣表現不錯。然而，她和其他人最大的不同在於她對於軟體以及電腦邏輯內部的了解。同事們很快就發現 了她的洞察力，當有重大的障礙無法突破時會來尋求她的幫助。而這也提供Sarah一個很好的機會可以接觸到一些她原本工作不會碰到的問題。&lt;/p&gt; &lt;p&gt;在 任職滿一年時，Sarah做了一件同事們覺得非常不可思議的事。她請求調到軟體測試部門。測試工作時常被誤認為是次一等而且前途發展有限的。軟體 測試人員的工作主要是檢查其他人的成果，確認軟體的執行和預期中的相同。和其他的研發工作相比，測試工作少了一些開發新產品所帶來的個人成就感。由於他們 總是帶來壞消息，例如軟體的臭蟲或是品質的問題，軟體開發工程師即使知道是必要的，通常也是很不情願，甚至略帶敵意地容忍測試人員的存在。&lt;/p&gt; &lt;p&gt;但是Sarah將測試工作視為一個新的機會，可以從完全不同的角度來了解她自己的工作。她將會廣泛地了解造成軟體錯誤的原因。可以在一兩年之內累積大量的經驗。同時，可以和最重要的客戶合作，一起開發客戶眼中合理的測試程式。&lt;/p&gt; &lt;p&gt;在這個過程中，Sarah可以學到在將來的軟體開發時，如何避免本質上及觀點上所會犯的錯誤。同時，測試工作也使得她有機會了解她同事們的觀點。她由同事們開發軟體的問題及排除的過程中學習到相當紮實的技巧。&lt;/p&gt; &lt;p&gt;兩年後，當Sarah重新回到軟體開發的工作時，她在測試部門的訓練開始展現在工作上。她的同事們很快就認定她是軟體大師。Sarah成為他們公司的軟體專家，帶領著公司在矽谷中力爭上游。&lt;/p&gt; &lt;p&gt;像Sarah這樣的傑出工程師，可以分辨不同觀點中的細微差異。這並不是因為有天份。而是因為他們主動追尋，並且將這個特質轉換成實質的幫助。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;5. 正確地追隨(The right kind of followership) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一般的工程師相信，擔任追隨者角色的重點在於嚴守分際，毫不遲疑地接受命令，同時不對主管造成威脅。&lt;/p&gt; &lt;p&gt;然 而，傑出的工程師很早就了解到，副手還可以有更正面的貢獻，一個傑出的第二號人物的真義在於專心做出幫助。他們主動而且積極地投入對組織（及主 管）的成功有幫助的事，同時，對於該做什麼及如何做，他們可以做出獨立而決定性的判斷。一個好的追隨者可以和主管充分配合來達成整個組織的目標，即時他和 主管之間的個性及工作文化並不相同。&lt;/p&gt; &lt;p&gt;這點可能會另許多人感到驚訝，因為一般人認為傑出的人應該都是主管或是焦點人物。通常，傑出的副手對主管所做的幫助在於對於可能有困難的地方事先提出警告，做一個心思縝密的共振板，或是質疑主管決定的正確性。&lt;/p&gt; &lt;p&gt;在 許多的科技公司中，公司相信客戶真正的需求和知識員工所認為最好的必須做出區別。我常常聽到老闆們和我抱怨當客戶需要的只是一部道奇車，而他的員 工們卻造了一部勞斯萊斯。技術員工往往對於製造出最好的相當執著，他們希望能把最先進的技術都用在產品中，即時這樣會造成時程延誤及增加預算。&lt;/p&gt; &lt;p&gt;但是有時對錯不一定是絕對的，一位貝爾實驗室的優秀工程師在主管質疑他做了額外的功能時據理力爭。他的主管希望能夠在電話交換機中採用簡化的轉接功能來提前完成產品提供給客戶。&lt;/p&gt; &lt;p&gt;她說：『先別管這些額外的功能，這個客戶寧可現在就有一個基本的機器可以用，而不希望因為一個更強的功能多等一個月。』&lt;/p&gt; &lt;p&gt;她的工程師回答：『未必是這樣』。並且和她坐下來討論這個產品對這個客戶及其他客戶的的短期和長期目標。&lt;/p&gt; &lt;p&gt;『沒 錯，短期內對這個客戶來說，這樣做可能有好處。』她的屬下說。『但是這樣做也有風險，他們可能會把我們歸類成較低階的產品線。同時，如果我們現 在將這個額外的功能加進去，我們已經在進行中的下個客戶的產品開發會省很多時間。不過，我們還是再和客戶確認一次他們的想法。』&lt;/p&gt; &lt;p&gt;這位優秀的追隨者了解他的主管最關心的問題。同時，他也試著將她的觀點轉移到他們共同的整體目標。在可能的狀況下，傑出的追隨者可以稍微修正他們的方向使得他們的努力和公司的目標吻合。不行的話，他們只好另外找一個更適合的公司。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;6. 團隊合作(Teamwork as joint ownership of a project) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一般的員工所了解的團隊合作是在計畫進行中或是解決問題時和他人合作，並且做好自己的部份。&lt;/p&gt; &lt;p&gt;傑出的工程師對團隊合作有更高一層的看法。他們將之視為一連串複雜的技巧，包含了參與設定共有的計畫目標，團隊承諾，工作紀律，時程，及分享團隊成就。同時，這也包含了主動促進團隊的互動–讓每個人都覺得是團體的一分子，處理衝突，並幫助其他成員解決問題。&lt;/p&gt; &lt;p&gt;有一個醫療器材供應商由於醫院對於他們最新型的加護監視器失效十分不滿，因此成立了一個危機處理小組來處理這件事。這個儀器會不定時的發出錯誤緊急的警告，使得病患和醫療人員都很困擾，醫療人員時常匆忙趕來處理緊急的狀況，才發現完全沒有問題。&lt;/p&gt; &lt;p&gt;這個處理小組包含了五個部門的專業人員，包含了生產，研發，及客戶服務的人員。在這個小組的7位成員中，只 Aiden最為優秀，他原本是一個工程師，為了多了解客戶服務相關的事務而調到客服部門。&lt;/p&gt; &lt;p&gt;在 小組第一次會議進行到了第 3 個小時的時候，成員們對於該立即採取的行動起了激烈的爭執。Ewing，一位53歲，在公司已經服務25年的生產工程師，希望說服其他人繼續派遣修護人員 到醫院維修。而 Julie，一位研究部門的新進人員，則希望能夠比照嬌生公司處理 Tyleno l事件的先例，全面回收產品。&lt;/p&gt; &lt;p&gt;隨著討 論的進行，Ewing 和 Julie 的爭論越來越白熱化，同時也越不文明。Aiden發現他自己以及其他人開始感到沮喪及煩躁。為了不讓這種狀況持續發展至不可收拾，Aiden 將他的感覺提出來，並且建議休會10分鐘，讓大家休息一下來想想有沒有轉圜的方式。&lt;/p&gt; &lt;p&gt;當會議繼續進行的時候，Aiden 請 Julie 來代言 Ewing 的意見，同時請 Ewing 替 Julie 的看法辯護，試著利用這種方法來打破僵局。雖然 Julie 和 Ewing 有點不太情願，這個策略有效地削減了逐漸升高的緊張及憤怒。這時，其他的小組成員開始腦力激盪，提出可能的想法。一位很有經驗但是害羞的設計師 Eloise，坐在角落的位置而且整天都還沒有發言。她用很溫和的聲音提出她的看法：『由於並不是每一家醫院都有相同的抱怨，我們是不是該先找出為什麼這 幾台機器會持續發生問題？或許這些機器本身一開始就有故障，也可能是這些機器安裝的醫院有一些特殊的地方。與其全面回收所有的產品，不如只將有問題的機器 收回來，同時檢查所有的設定資訊來查出到底問題出在那裡，說不定是磁場太高之類&lt;br /&gt;的現象造成的。』&lt;/p&gt; &lt;p&gt;她講完時，並沒有其他的成員回應她的想法。討論繼續進行了幾分鐘之後，Aiden 加入討論並提醒大家：『我不確定是不是每個人都聽到剛剛 Eloise 的建議，我想她的方法應該可以幫我們解決這個事件，現在是不是可以請妳再說一次給大家聽？』&lt;/p&gt; &lt;p&gt;Eloise 再一次地提出她的想法，Aiden 注意到這個建議不但展現了對客戶的問題認真回應，同時也比全面回收成本低。其他的小組成員開始支持 Eloise 的方法來化解僵局，然後開始討論後續的議題。&lt;/p&gt; &lt;p&gt;如果不是 Aiden 出面干涉，Ewing 和 Julie 可能還在爭吵，Eloise 的意見可能永遠不會被注意到，整個小組不知道還要掙扎多久。雖然 Aiden 在小組中的角色是客戶服務部門的代表，他做了超越他職責的努力而增進了團隊的效能。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;7. 小領導者的領導風格(Small-l leadership) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一般人很著迷於大領導者的領導風格 (Big-L Leadership): 大願景，大魅力，大成功。對他們而言，領導能力是與生俱來的天份。擁有這種天份的人能透過掌權來炫耀自我，對最重要的事情有決定權，同時對於向下授權之類的事並不感興趣。&lt;/p&gt; &lt;p&gt;傑 出的員工則將領導能力視為一種工作策略，運用於自己的專業能力及影響力來說服一群人團結起來，一起完成重要的工作。這項工作包含了許多方面的努 力：幫助團隊創造一個清楚的願景，建立信任並獲得承諾來努力完成任務。爭取足夠的資源以順利達成目標。同時指導整個計畫的進行直到順利執行完畢。&lt;/p&gt; &lt;p&gt;我 們都知道有些人非常聰明，卻沒辦法領導最小的計畫。除了智力之外，還要具備其他的能力才能展現小領導者的領導風格(Small-l leadership)。小領導者了解人與人之間微妙的關係，而大領導者則專注在自己的想法，自己的工作風格，與自己的目標。小領導者知道他們必須考慮所 有團隊成員的需求，技能，渴望，及權力。&lt;/p&gt; &lt;p&gt;這種將注意力放在自己以外的領導風格在職場現實上是比較有生產力的。小領導者通常對於他所領導的 團體沒有正式的職權。同事們只有在確定團隊中的領導 者對於自己和其他人的利益一樣重視時才願意參與。因此，要將團隊組合起來需要和所有的成員互動，溝通，這對於大領導者而言，是浪費寶貴的領導時間。然而， 一個願意和所有團隊成員同甘共苦的小領導者，往往比最有魅力的大領導者主管更能獲得成員的忠誠及信任。&lt;/p&gt; &lt;p&gt;傑出領導者的最大秘訣，也是和大領導者及表現普通的領導者最大的差異，在於他們不會假設他們對於其他人的一切事情都能完全掌握。大多數的大領導者相信自己是無所不能的，他們知道什麼是對成員及狀況最好的處置。&lt;/p&gt; &lt;p&gt;傑 出的小領導者總是會先詢問成員的意見，即使他們覺得他們已經知道結果。Anithia, 一位德商公司在美國的軟體設計師，在開始計畫之前一定會先驗證她對同事們想法的假設是否正確。當她被指派去帶領一個開發網路軟體的計畫時，她在第一次的會 議就先詢問成員們對於工作角色和任務的意見。&lt;/p&gt; &lt;p&gt;『John, 在上次和你一起執行計畫時，你曾提到你希望能有更多的硬體經驗，目前還是這樣嗎？因為這個計畫硬體的部份非常重要。』&lt;/p&gt; &lt;p&gt;Anithia 像一個認知心理學家一樣暫停自己的假設，提出一些開放性的問題，讓成員們可以表達他們目前具備的技能以及他們對於計畫的期望及需求。 因此，她可以將任務的分配和成員的能力及興趣做更好的配合。她希望能夠避免將她的同事定型，不要像好萊塢製作人一樣製造演員的刻板印象。&lt;/p&gt; &lt;p&gt;當 然，身為員工不可能總是獲得所有想要任務與福利。但是，沒有正式職權的小領導者可以藉由真誠的聆聽及試著滿足部份的需求來贏得認同。同時這個努力 溝通的過程也可以為計畫打下互信的基礎，幫助度過計畫遇到困難時無可避免的壓力。在某一個技術領域展現優越的實力可能可以幫助一個傑出的工程師被指派為團 隊的領導者。但是小領導者知道階層的力量並不能延伸到人際關係這一方面。他們會試著創造出一種氣氛，讓成員們感受到『我們是在同一艘船上』。&lt;/p&gt; &lt;p&gt;Anithia 所領導的計畫後來客戶的反應非常好。在年終慶功的晚宴上，北美部門的總裁對Anithia大加讚賞，邀請她一起到台上來表揚這個計畫 及她以前所領導計畫的成功。他說：『如果我們公司有500個像Anithia這樣的人，控制整個北美市場是遲早的事。』然後，他請Anithia講幾句 話。&lt;/p&gt; &lt;p&gt;就像許多演員獲得奧斯卡獎時一樣，Anithia可以很快的講一些感謝上司及成員的話。而她卻不是這樣做。她邀請了所有的團隊成員一 起到台上來，請 其中的一位將所有的人介紹給大家，然後她說：『這個計畫是我們共同努力的成果，沒有每一個人的貢獻，不可能有今天的成功，我們對於這個計畫感到很驕傲，非 常高興你們也這樣想。』然後他們一起對大家鞠了一個躬。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;8. 精明(Street smarts) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一般人多半太專注在討人喜歡，以為這樣是在職場中快速升遷的方法。他們要不就是對於辦公室內的政治問題太過關心，要不就是故意裝作完全不在乎。&lt;/p&gt; &lt;p&gt;傑 出的員工了解任何的組織中都有許多正當而互相競爭的利益。藉由他們對組織運作的理解力，可以幫助他們在這些互相牴觸的競爭中，促成合作，凸顯衝突 的部份，並且讓任務順利完成。這個動作包含了具備處理個人及團隊動態的傑出運作能力，知道何時該避免衝突，何時該正面對決，同時知道如何將可能的敵人轉化 為盟友。&lt;/p&gt; &lt;p&gt;記得Sarah嗎？在第4項工作策略中提到的傑出軟體開發工程師。雖然她的同事都覺得她瘋了，她仍然自願請調到測試部門。這個動 作不但讓她對她的工 作有不同的觀點，她同時也知道那些人會和她日後的工作相關，並開始建立良好合作的關係。這種組織上的聯繫不但可以提高她的地位，還可以讓日後工作上的互動 更加順利。&lt;/p&gt; &lt;p&gt;在第3項工作策略中提到的Elena，運用了大量的組織運作機智來影響她的公司，將營運的焦點轉移到ISO 9000及歐洲市場的機會。首先，她利用午餐會議的機會將她在研討會中學到的傳授給她的同事。在她對這個議題更加了解之後，她舉辦了更詳細的訓練課程。同 時，她向她的上司仔細解釋這個特殊標準對公司的好處，並且藉由寄送關於業務及營收潛力的相關文件及備忘錄慢慢遊說管理階層。當然，在和更上層的管理者接觸 之前她一定會先得到她上司的准許。接著她開始訓練她的其他同事如何贏得歐洲客戶的標案。由此可看出，在她試著推銷她的想法的同時，她將這個想法和公司的重&lt;br /&gt;要目標結合在一起。同時也很注重組織運作的禮儀。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;9. 呈現(Show and tell) &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一般員工認為呈現就是利用炫目的簡報，長篇的備忘錄，或是公開展示自己的成果來吸引管理階層的注意。他們的重心擺在自己的形象以及自己所要傳達的訊息，而不是擺在聽眾。&lt;/p&gt; &lt;p&gt;傑出的工程師則會仔細篩選所要表達的資訊，以最有效，最友善的格式來傳遞訊息並說服特定的聽眾。就最高層次而言，呈現的意義在於對於特定的聽眾選擇適當的訊息，或是對特定的訊息選擇適當的聽眾。&lt;/p&gt; &lt;p&gt;呈 現的重要性是無法迴避的。一位專業人員如果無法有效地以簡報的方式傳達自己的想法給其他的人，在現今的職場中要生存是相當艱苦的。對於大多數的知 識工作者而言，這裡討論的重點並不是大型的演說，像比爾蓋茲在超大型的會議中心以最先進的多媒體設備及電腦特效所做的展示。而是針對在公司內部的小型會議 室中，對5至20位聽眾所做的簡報。簡報的聽眾多半是同事，上司，或是客戶。而內容多半是技術性的或是與產品相關的議題。&lt;/p&gt; &lt;p&gt;對傑出的專業人員而言，簡報準備的過程比較複雜。我們的研究觀察到呈現的表達方式會逐漸修正，由單純的傳達資訊轉變為對訊息的塑造。傑出的工程師通常精通將訊息傳達給特定的對象，說服聽眾接受所要表達內容，及事先對可能產生的批評做出準備的能力。&lt;/p&gt; &lt;p&gt;一般人最常見的錯誤會發生在由單純的資訊傳達，提升到試圖運用這個訊息發揮影響力時。在這個過程中，他們聽眾的組成已經大不相同了。然而，他們呈現的風格及的結構卻維持和原來一樣。&lt;/p&gt; &lt;p&gt;一位財星500大企業的勞工關係經理在和公司的工會協商新的合約時，面臨了必須降低醫療照顧成本的問題，他以極佳的呈現方式來解決這個問題。在這個協商的過程中，他所擬定的計畫必須同時被公司的最高主管及工會接受。&lt;/p&gt; &lt;p&gt;他 的主要處理方式是將相同的資訊塑造成完全不同的表現方式。首先他針對一群較低階的工會職員進行為期一週溝通，每天簡報一小部份的資訊。他發給他們 清晰而容易閱讀的講義，讓他們可以複製給所有的工會成員。講義的內容淺顯得讓人可以快速理解。這個呈現的主軸在於傳達一個訊息，如果工會同意改變醫療照顧 的計畫。公司承諾將所省下來的資金用來更新老舊的工廠設備，使得工廠更具競爭力。同時降低關場及失業的風險。&lt;/p&gt; &lt;p&gt;而他稍早對公司的執行長及副 總裁所做的簡報基本上含有相同的資訊，但是卻用完全不同的方式來包裝。首先，和對工會簡報相比最大的不同是互動的時間少 了很多。因此，大部分的資訊包含在一份詳細的報告中。他以其中有一個很具有說服力的章節來建議接受新的計畫。此外，他有一個小時的時間可以對公司的執行長 及董事長進行簡報來加強他的論點。&lt;/p&gt; &lt;p&gt;他在簡報中強調，如果管理階層執意改變醫療照顧計畫而沒有任何有創意的補償計畫，工會將不會同意而使協商幾乎不可能進行。他提醒公司目前才剛進入一個快速成長期，股東們可能無法忍受員工罷工。&lt;/p&gt; &lt;p&gt;雖然雙方陣營都對他的計畫有一些批評，然而，這位優秀的協商者已經將這個計畫的基礎打得很穩固了。到了最後，管理階層及工會都接受了他的建議案，只做了小部份的更動。&lt;/p&gt; &lt;p&gt;在這個案例中有許多值得學習的呈現技巧。但是其中最重要的，也是一般人和高手最大的不同點在於：了解你的聽眾，並且藉此塑造所要傳達的訊息。&lt;/p&gt; &lt;p&gt;Meara 的工作是設計影像傳輸軟體，可以透過電話線路在醫院的急診室之間傳遞X光片，心電圖指數，及即時的電視畫面。她用了一個電視短片作為簡報 的開頭，來對急診室醫師及醫院主管介紹她的團隊所設計的最新軟體。短片以汽車的緊急煞車聲和救護車的警報聲開始，一個小孩被緊急送入急診室，一位醫師開啟 她們公司的儀器並且說他只有幾分鐘的時間可以來挽救一條年輕的生命。&lt;/p&gt; &lt;p&gt;她說：『我們目前的進展可能可以挽救這個孩子，或是你的孩子的生命。在我們計畫進行中，我們不斷的觀看這個短片來提醒自己，盡量將產品做到最好有多重要。現在，請和我們分享我們的成果。』&lt;/p&gt; &lt;p&gt;為 了展現新的軟體和之前版本的差異，Meara使用了電子計時器搭配心跳聲做示範。首先，她使用舊版的軟體，在所有的聽眾還在等待螢幕上慢慢傳來的 畫面時，計時器已經跑完了，心跳聲停止了，手術室的警告燈也熄滅了。而當使用新的軟體展示時，畫面傳輸的速度變快，在計時器停止之前已經完成影像的傳輸。&lt;/p&gt; &lt;p&gt;然後Meara向她的聽眾解釋在產品開發的過程中為了縮短傳輸時間所做的努力。包含了那些嘗試是有幫助的，那些則沒有用，以及其中的原因。她將技術上的論點和醫療專業人員挽救性命的過程戲劇化地編織在一起。&lt;/p&gt; &lt;p&gt;Meara藉著讓她的聽眾們感受到自己的孩子被送進急診室的恐懼，吸引聽眾們的注意力到公司的產品。然後戲劇性地展示了新產品的價值。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;成為閃亮的明星 &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;我 們對於我們的生產力提昇計畫做了長期的成效評估。觀察工程師們在學習了這些工作策略之前和之後生產力的差異。在過去的7年之中，有超過 1000 位美國及歐洲的專業工作者受過這個訓練。這個訓練課程曾經授權給專業的訓練機構，同時也有大學將這套計畫用於課堂上以及職員的成長計畫。&lt;/p&gt; &lt;p&gt;為了提供評估的基準，我們訪問了主管，傑出的工程師，及一般的員工，請他們列出明顯顯示出生產力提昇的衡量標準。在經過許多次的反覆實驗之後，我們確認了滿足這些衡量標準的員工，在生產力上確實有明顯的提昇。&lt;/p&gt; &lt;p&gt;然後我們訪問了 300 位參加者及 300 位沒有參加人員的直接主管，根據這些衡量標準來評分，第一次評分是在參與計畫之前，第二次則是在完成計畫之後 8 個月。&lt;/p&gt; &lt;p&gt;在這個主管評分的分析中，參與計畫的人員在生產力上都有顯著的提昇。參加過這個訓練的工程師不但解決問題的速度變快，工作產出的品質也提昇了，同時不斷地讓他們的客戶感到驚喜。&lt;/p&gt; &lt;p&gt;這個傑出工作策略的計畫並不是用來矯正生產力低落的員工。參與計畫的人員中，有30%是本來表現就已經很優秀了。然而，他們生產力的提昇仍然是相當顯著。&lt;/p&gt; &lt;p&gt;生產力提昇最顯著的是女性及少數民族的工程師。根據他們上司的說法，參與計畫前後的生產力差異平均值可以達到400%。&lt;/p&gt; &lt;p&gt;這個訓練計畫的成功驗證了我們研究的主要發現。要大幅提昇生產力並不需要魔法。當一個工程師表現平平時，通常不是因為他的能力不足。而是因為他從來沒有學過可以提高他生產力的工作策略。一旦他了解了這些策略，他就開始邁向傑出之路。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-5921706341934724264?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/5921706341934724264/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=5921706341934724264' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/5921706341934724264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/5921706341934724264'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/10/blog-post.html' title='[轉載]如何成為一位傑出的工程師'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-3373991519062205896</id><published>2008-10-31T06:35:00.000-07:00</published><updated>2008-10-31T06:48:25.512-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/軟體開發'/><title type='text'>[轉載]Android配合Eclipse環境建置</title><content type='html'>1. 建立目錄 D:\Android&lt;br /&gt;&lt;br /&gt;2. 下載 Google Adnroid SDK&lt;br /&gt;http://code.google.com/android/download.html&lt;br /&gt;解壓後改名"android_sdk_windows_m3-rc20a" -&gt; "android_sdk"&lt;br /&gt;放到D:\Android\android_sdk&lt;br /&gt;&lt;br /&gt;3. 下載 eclipse(ex:Eclipse Classic 3.3.1.1)&lt;br /&gt;http://www.eclipse.org/downloads/&lt;br /&gt;解壓後放在D:\softwate\eclipse&lt;br /&gt;&lt;br /&gt;4. 下載並安裝JDK (ex:Java SE Development Kit 6 Update 4)&lt;br /&gt;網址：http://java.sun.com/javase/downloads/index.jsp&lt;br /&gt;設定系統PATH：我的電腦右鍵-&gt;內容-&gt;進階-&gt;環境變數-&gt;PATH-&gt;編輯-&gt;加上你的JRE安裝路徑(比如：C:\Program Files\Java\jre1.6.0_04\bin)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_VqtpRmnXNR0/R5x0eE9yU7I/AAAAAAAAAGE/mki4fdfycBo/s1600-h/path.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp0.blogger.com/_VqtpRmnXNR0/R5x0eE9yU7I/AAAAAAAAAGE/mki4fdfycBo/s400/path.JPG" alt="" id="BLOGGER_PHOTO_ID_5160127333137535922" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;5. 安裝 Android Eclipse Plugin&lt;br /&gt;5.1 Eclipse-&gt;Help-&gt;Software Update-&gt;Find and Install-&gt;Search for new features to install&lt;br /&gt;5.2 按下New Remote Site&lt;br /&gt;Name:Android&lt;br /&gt;URL:https://dl-ssl.google.com/android/eclipse/&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_VqtpRmnXNR0/R5xTYU9yU5I/AAAAAAAAAF0/eUpMV_OrgHQ/s1600-h/reomte.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp1.blogger.com/_VqtpRmnXNR0/R5xTYU9yU5I/AAAAAAAAAF0/eUpMV_OrgHQ/s400/reomte.JPG" alt="" id="BLOGGER_PHOTO_ID_5160090950469571474" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;(如果之前已經安裝過，先到Eclipse Help-&gt;Software Update-&gt;Manage Configure找到Andriod Development Tools，右鍵，Uninstall)&lt;br /&gt;&lt;br /&gt;6. 指定Android SDK的位置&lt;br /&gt;Eclipse-&gt; Window -&gt; Preferences -&gt; Android  -&gt; SDK Location -&gt; "D:\Android\android_sdk"&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_VqtpRmnXNR0/R5xTUE9yU4I/AAAAAAAAAFs/N0S60MHBREc/s1600-h/reference.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp0.blogger.com/_VqtpRmnXNR0/R5xTUE9yU4I/AAAAAAAAAFs/N0S60MHBREc/s400/reference.JPG" alt="" id="BLOGGER_PHOTO_ID_5160090877455127426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;7. 建立第一個程式：HelloAndroid&lt;br /&gt;Eclipse -&gt; File -&gt; New -&gt; Project -&gt; Android Project&lt;br /&gt;Project Name:HelloAndroid&lt;br /&gt;Package Name:com.google.android.hello&lt;br /&gt;Activity Name:HelloAndroid&lt;br /&gt;Application:Hello, Android&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_VqtpRmnXNR0/R5xTK09yU2I/AAAAAAAAAFc/4NleS814UMM/s1600-h/newproject.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp3.blogger.com/_VqtpRmnXNR0/R5xTK09yU2I/AAAAAAAAAFc/4NleS814UMM/s400/newproject.JPG" alt="" id="BLOGGER_PHOTO_ID_5160090718541337442" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;在HelloAndroid.java貼上程式碼：&lt;br /&gt;&lt;p&gt;&lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;package&lt;/span&gt;&lt;/b&gt;  com.google.android.hello;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;import&lt;/span&gt;&lt;/b&gt;  android.app.Activity;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;import&lt;/span&gt;&lt;/b&gt;  android.os.Bundle;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;import  &lt;/span&gt;&lt;/b&gt;android.widget.TextView;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;class&lt;/span&gt;&lt;/b&gt; Hello  &lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;extends&lt;/span&gt;&lt;/b&gt; Activity {&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;     /** Called when the activity is first created. */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;   &lt;span style="color: rgb(102, 102, 102);"&gt; @Override&lt;/span&gt;&lt;br /&gt;&lt;b&gt;    &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;public&lt;/span&gt;&lt;/b&gt; void onCreate(Bundle icicle) {&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;    super&lt;/span&gt;&lt;/b&gt;.onCreate(icicle);&lt;br /&gt; TextView tv =  &lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;new&lt;/span&gt;&lt;/b&gt; TextView(&lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;this&lt;/span&gt;&lt;/b&gt;);&lt;br /&gt; tv.setText("&lt;span style="color: rgb(0, 0, 255);"&gt;Hello,  Android&lt;/span&gt;");&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;     this&lt;/span&gt;&lt;/b&gt;.setContentView(tv);&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;在專案上，右鍵，Run as，Android Application&lt;br /&gt;接著就會出現模擬器，往左邊選擇Applications&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_VqtpRmnXNR0/R5xVLU9yU6I/AAAAAAAAAF8/b26pTvwhOfA/s1600-h/application.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp1.blogger.com/_VqtpRmnXNR0/R5xVLU9yU6I/AAAAAAAAAF8/b26pTvwhOfA/s400/application.JPG" alt="" id="BLOGGER_PHOTO_ID_5160092926154527650" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;選擇Hello, Android&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_VqtpRmnXNR0/R5xTBU9yU0I/AAAAAAAAAFM/c2GIfDspjWs/s1600-h/Hello.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp1.blogger.com/_VqtpRmnXNR0/R5xTBU9yU0I/AAAAAAAAAFM/c2GIfDspjWs/s400/Hello.JPG" alt="" id="BLOGGER_PHOTO_ID_5160090555332580162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;出現執行畫面了！&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_VqtpRmnXNR0/R5xTQ09yU3I/AAAAAAAAAFk/JnSbvC01AhI/s1600-h/last.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp3.blogger.com/_VqtpRmnXNR0/R5xTQ09yU3I/AAAAAAAAAFk/JnSbvC01AhI/s400/last.JPG" alt="" id="BLOGGER_PHOTO_ID_5160090821620552562" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-3373991519062205896?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/3373991519062205896/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=3373991519062205896' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3373991519062205896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3373991519062205896'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/10/androideclipse.html' title='[轉載]Android配合Eclipse環境建置'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_VqtpRmnXNR0/R5x0eE9yU7I/AAAAAAAAAGE/mki4fdfycBo/s72-c/path.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-3976230065042164412</id><published>2008-10-22T17:18:00.000-07:00</published><updated>2008-10-22T17:31:01.858-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/Windows應用'/><title type='text'>XP 多人遠端登入</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style=";font-family:courier new;font-size:180%;"  &gt;&lt;span style="color: rgb(255, 0, 0);"&gt;本&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;篇為轉載文章&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;來源不詳，若有知道作者為誰，歡迎告知，小弟會再修改放上，謝謝&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;緣 由 : XP Pro 的遠端桌面只允許一個人連線，當其他使用者使用遠端桌面連線到 XP Pro 時，&lt;br /&gt;本機使用者會被強制登出。只要完成下列步驟，&lt;br /&gt;就可以解除這個限制，經實測確實可行&lt;br /&gt;(測試機器為 XP Pro SP2 Vol 版本，本機主控台一個工作階段加上兩部電腦遠端登入)。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;1.&lt;/span&gt; &lt;/span&gt;將 Windows 啟動在安全模式。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;2.&lt;/span&gt; &lt;/span&gt;按一下 [控制台] 中的 [系統]，取消選取 [遠端] 索引標籤中的&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;   [允許使用者遠端連線   到這部電腦]，然後按一下 [確定]。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;3. &lt;/span&gt;開啟 [控制台][系統管理工具][服務]，將 Terminal Services 服務停用，&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   然後按一下[確定]。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;4. &lt;/span&gt;瀏覽到 C:\windows\system32\dllcache 目錄，將termsrv.dll 檔案改成&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   別的名稱 (例如 termsrv.original)。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;5.&lt;/span&gt; 從 http://www.orbitfiles.com/download/id20947665 下載無連線數目限制&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   的 termsrv.dll，然後將它複製到C:\windows\system32\dllcache 目錄。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;6.&lt;/span&gt; 瀏覽到 C:\windows\system32 目錄，重複步驟 4 與步驟 5&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   (將 termserv.dll 改成其他名稱，然後將剛下載的檔案複製到此目錄。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;7. &lt;/span&gt;開啟 [登錄編輯程式]，找到&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   Terminal Server\Licensing Core 機碼。新增一個名為&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   EnableConcurrentSessions 的 DWORD 項目，將其值設定為 1，&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   然後關閉 [登錄編輯程式]。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;8. &lt;/span&gt;按一下 [ 開始][執行]，輸入 gpedit.msc，然後按一下ENTER。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   開啟 [電腦設定][系統管理範本][Windows 元件][終端機服務]，&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   按兩下 [限制連線數目]，選擇 [已啟用]，然後在&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   [可允許的 TS 最大連線數目] 中設定想要的最大連線數目。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;9.&lt;/span&gt; 重新啟動 Windows 在正常模式。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;10.&lt;/span&gt; 按一下 [控制台] 中的 [系統]，選取 [遠端] 索引標籤中的&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   [允許使用者允端連線到這部電腦]，然後按一下 [確定]。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;11.&lt;/span&gt; 開啟 [控制台][系統管理工具][服務]，將 Terminal Services 服務啟動，&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    然後按一下 [確定]。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;12. &lt;/span&gt;重新啟動 Windows。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;font-family:courier new;font-size:180%;"  &gt;注意：&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;1. &lt;/span&gt;您必須為使用者建立帳戶並將他加入 Remote Desktop User群組，&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   該使用者才能連線。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;2.&lt;/span&gt; 您可能必須啟用「快速使用者切換」與「歡迎畫面」，按一&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   下 [開始][控制台][使用者帳戶][變更使用者登入或登出的方式]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   以啟用上述兩個功能。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;3.&lt;/span&gt; 此解決方案可能不適合已加入網域的電腦，因為網域群組原則可能&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   會覆寫本機群組原則。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;p style="font-weight: bold; color: rgb(255, 0, 0);"&gt;&lt;span style="font-size:130%;"&gt;問答集：&lt;/span&gt;  &lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;問：&lt;a href="http://www.orbitfiles.com/download/id20947665"&gt;http://www.orbitfiles.com/download/id20947665&lt;/a&gt; 這檔案哪來的？&lt;br /&gt;答：據聞取自 XP SP2 RC1，termsrv.dll 版號 5.1.2600.2055。  &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;問：在開啟 [自動更新] 的情況下，這個檔案會被更新為最新的版本嗎？&lt;br /&gt;答：不清楚，個人並不使用 [自動更新]。照理說如果這個檔案沒有被發現有弱點，MS 應該不會釋出更新。  &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;問：這個方式適用於 XP Home 版本嗎？&lt;br /&gt;答：不清楚，個人沒有 Home 版本，只有在 XP Pro 版本測試過可行。或許您可以試試然後告訴大家結果。  &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;問：會不會有任何安全上的問題？&lt;br /&gt;答：不清楚，請自行負擔所有風險。&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-3976230065042164412?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/3976230065042164412/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=3976230065042164412' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3976230065042164412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3976230065042164412'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/10/xp.html' title='XP 多人遠端登入'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-894848002068024836</id><published>2008-06-27T21:00:00.001-07:00</published><updated>2008-06-27T21:20:08.054-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/Firmware'/><title type='text'>BIOS for VGAint</title><content type='html'>(轉貼於"小華的部落格http://biosengineer.blogspot.com/")&lt;br /&gt;&lt;br /&gt;一般而言,BIOS會在POST時 locate 3 devices:&lt;br /&gt;- Input device(Ex. Keyboard)&lt;br /&gt;- Output device(Ex. Display device)&lt;br /&gt;- IPL(Initial Program Load, Ex. HDD)&lt;br /&gt;&lt;br /&gt;這次要提到的是 Display device,即 VGA !&lt;br /&gt;&lt;br /&gt;在PCI_SCAN之後,BIOS會在記憶體中建立一個data structure,代表整個系統的 PCI architecture.&lt;br /&gt;Ex. Ponter-&gt; NB-&gt;P2P-&gt;SB-&gt;IDE-&gt;AUDIO-&gt;LAN-&gt;USB 2.0-&gt;USB 1.1-&gt;...-&gt;VGA-&gt;...-&gt;End&lt;br /&gt;&lt;br /&gt;在VGA_init的階段,BIOS會去 go-through this list,一個個的問:"有沒有人需要shadow Option ROM的 ?"&lt;br /&gt;&lt;br /&gt;-------------------------------&lt;br /&gt;*1 在此,先break,並說明一些觀念:&lt;br /&gt;1. Option ROM是 for H/W的 firmware;像BIOS一樣是 for MB.有可能直接在硬體上 ,or 包在BIOS image中&lt;br /&gt;2. 有Option ROM的 H/W可能有: VGA card,Lan card, RAID card,...etc&lt;br /&gt;3. VGA's Option ROM 也就是 VBIOS ! 專門處理 screen I/O operation(主要是int10h)&lt;br /&gt;4. VGA "shadow" 即代表: 將 VBIOS copy 到 shadow RAM, Ex. C0000h~C7FFFh處(32K)&lt;br /&gt;5. VGA init這個階段只 consider "VGA device" ! for 其他 device,之後再考慮其 shadow的事宜&lt;br /&gt;-------------------------------&lt;br /&gt;&lt;br /&gt;(承接前面的 flow):此時,VGA device會舉手說:"我要" !此時,BIOS會去尋找VGA device's Option ROM(即VBIOS)在哪裡;此時,VBIOS有可能在card上 or "當初" 被包在 BIOS image中(*2)&lt;br /&gt;&lt;br /&gt;一但找到,則會先 作一些 checks:Ex.&lt;br /&gt;- Option ROM signature is 0xAA55 ?&lt;br /&gt;- 比較 Option ROM內的 Vendor ID/Device ID = H/W's IDs ?&lt;br /&gt;- class code and sub-class code correct ?&lt;br /&gt;- length = 0 ?&lt;br /&gt;...etc...&lt;br /&gt;&lt;br /&gt;若都符合,則視它為 VGA Option ROM(VBIOS) ! 之後,利用 memory2memory copy將之 copy到 shadow memory,從 C0000h處開始存放...&lt;br /&gt;&lt;br /&gt;複製完後,再 check "checksum"是否正確;if yes then jump to "entry of initialization code",控制權自此轉移至 VGA Option ROM,由它去做 initialize VGA的工作 ! ( 若是CRT螢幕,user會聽到ㄉ一ㄤ的一聲 ! 即代表 initialize VGA成功 !!! )&lt;br /&gt;&lt;br /&gt;&lt;- 此為 VGA_init的工作 !!!  *2 說"當初"的原因是: VGA BIOS若包在BIOS image中,在 BIOS shadow時,也會被一併 copy到記憶體的某處放著;當然,會記住存放處 !  [Note] 一般遇到 VGA init fail的issue時,可以先 check:是否 VGA BIOS已被 copy 至 C0000h處;若有,則check是否已經 jump to VBIOS or NOT;若否,則可以往前 check是否前面所列的一些 "關卡"沒過 (Ex. ID不 match, or checksum 不相等...etc )   VGA 若 ok,電腦就是彩色的 ^_^  &lt;strong&gt;---------------------------&lt;br /&gt;- 相關討論 -----------------&lt;br /&gt;---------------------------&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;通常都是板子一來就會去開始Debug VGA...&lt;br /&gt;VBIOS 若壞，螢幕是黑ㄟ&lt;br /&gt;VBIOS若好，螢幕是彩色ㄟ&lt;br /&gt;沒螢幕的情況下要繼續Porting BIOS就比較麻煩一點&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[Q]Option ROM是 for H/W的 firmware;像BIOS一樣是 for MB.有可能直接在硬體上 ,or 包在BIOS image中。前者我叫它SW ROM,後者叫legacy ROM，您已經提到sw rom的load方式，那麽legacy rom load方式是否應該有所不同呢？一但找到OpROM,則BIOS 會先作一些 checks:&lt;br /&gt;Ex.&lt;br /&gt;- Option ROM signature is 0xAA55 ?&lt;br /&gt;- 比較 Option ROM內的 Vendor ID/Device ID = H/W's IDs ?&lt;br /&gt;- class code and sub-class code correct ?&lt;br /&gt;- length = 0 ?&lt;br /&gt;...etc...&lt;br /&gt;&lt;br /&gt;兩种rom都是通過這種方式嗎？ &lt;/strong&gt;&lt;br /&gt;Ans: 我所說的都是 rough flow，而這兩種ROM的"處理方式"不同,但"檢查的機制"大同小異...建議去trace BIOS code比較清楚&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[補充1]&lt;/strong&gt;&lt;br /&gt;1.可以查看PCI ROM Spec... 裡面有詳細說明如何Load OpROM 的方式，而檢查項目就各家BIOS不同...&lt;br /&gt;&lt;br /&gt;2.可以用HEX編輯器直接開啟ROM File，例如VBIOS.bin or OpROM.dat ...etc 來查看內容(Binary file)，例如某VBIOS.DAT 的內容如下:&lt;br /&gt;&lt;br /&gt;00000 55 AA 80 E9 4B ....&lt;br /&gt;00010 30 30 00 22 E9 19 21 5F 40 00&lt;br /&gt;.......................................&lt;br /&gt;00040 50 43 49 52 86 80 42 2A ..............&lt;br /&gt;&lt;br /&gt;其中:&lt;br /&gt;a)55AA是這個ROM的Signature &lt;--代表他是符合規範的ROM b)80 這個ROM的Code size  &lt;--需查閱Spec確定一下 c) 接著是EntryPoint Address &lt;--實際上會執行的程式碼進入點的位址，所以一般都是講     Jmp OpRomBaseAddr+3 &lt;-- 你如果trace BIOS 程式碼，這就是 +3 的由來 d) 000018h=40 代表另一個PCI Header在Offset 00040h的地方      所以 50 43 49 52 是Signature，如果用ACSII 來看就是"PCIR"     其他更多資訊可以查看PCI ROM Spec說明.....  e) "PCIR"後面緊跟著這個OpRom的VID與DID ...即8086 2A42 &lt;--Intel=8086  3.如果想要改OpRom裡面的Code，可以使用反組譯工具去修改或是用Debug去修改 如果比較簡單的OpROM要做實驗的話我都用Debug.com 把OpROM 載入到Mem，接著利用T /P 指令單步執行去追蹤與修改，修改好之後再查看機器碼，再利用Hex編輯器 or 反組譯工具寫回去OpROM (找Bug時可以嘗試這樣寫啦，不過違反智慧財產權，最好還是叫Vendor幫你改，而且光看懂OpROm的流程就需要一點時間了 ^^!)  如果要用組合語言寫一個Dummy OpRom的做法就像下面範例去模擬一個OpROM... 至於你BIOS端可不可以run 就要看你的檢查機制嚴謹程度或是你自己修改你的BIOS code來達到模擬的目的 : .586p .code YourCodeStart: ORG 0 db 55h, 0AAh TotalCodeSize db (offset YourCodeEnd) - (offset YourCodeStart)      ORG 3 jmp entrypoint  entrypoint:      ........  YourCodeEnd:      END  組譯完之後可以利用微軟工具EXE2BIN.EXE 把他轉成xxx.bin (binary file)然後你就可以包進去BIOS測試。  &lt;strong&gt;[補充2]&lt;/strong&gt;&lt;br /&gt;當VGA init時,那時VGA BIOS的放置處可能有:&lt;br /&gt;case 1: 在 memory中(當初在 shadow stage時被 copy 到 memory)&lt;br /&gt;case 2: 在 card上(Ex. 一般的 external VGA card上都有一顆小rom)&lt;br /&gt;&lt;br /&gt;因此,這兩種case的處理方式便不同.&lt;br /&gt;Ex. In case 2 若VGA card在 bridge後面,則還需要 config 該 bridge's resource window使Option(in card)可以被正確的 accessed...&lt;- 所以處理方式有所不同 !&lt;br /&gt;&lt;br /&gt;至於檢查機制;因為Option ROM不管放哪裡,其 content都是一樣 ! 因此檢查機制大同小異...還有,不同家BIOS的 "checks" 也未必完全相同 !!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-894848002068024836?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/894848002068024836/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=894848002068024836' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/894848002068024836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/894848002068024836'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/06/bios-for-vgaint.html' title='BIOS for VGAint'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-6154036058327693281</id><published>2008-06-27T20:58:00.000-07:00</published><updated>2008-06-27T21:19:51.768-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/Firmware'/><title type='text'>BIOS for PCI</title><content type='html'>(轉貼於"小華的部落格http://biosengineer.blogspot.com/")&lt;br /&gt;&lt;br /&gt;[About PCI device]&lt;br /&gt;1. 每一個PCI device都有其 unique PFA(PCI Function Address). PFA由 bus number,device number &amp;amp; function number所組成.&lt;br /&gt;&lt;br /&gt;Ex. USB device PFA is (0,6,0) &lt;- USB is a PCI device and its bus/dev/function is 0/6/0   2. 有了PFA,就可以存取其 PCI configuration registers.  Ex. write USB PCI register 43h bit1 = 1 =&gt;&lt;br /&gt;mov eax, 80003040h&lt;br /&gt;mov dx, 0cf8h&lt;br /&gt;out dx, eax&lt;br /&gt;&lt;br /&gt;mov dx, 0cffh&lt;br /&gt;in al, dx&lt;br /&gt;or al, 00000010b&lt;br /&gt;out dx, al&lt;br /&gt;&lt;br /&gt;* IO port 0cf8/0cfc 為 PCI config address port &amp;amp; data port,意即:將 address(80003040h)送到config port(0cf8h),然後從 data port(0cfch + 3)來存取 data(al)&lt;br /&gt;&lt;br /&gt;* 注意: 32-bit address(80003040h) 中 bit[1:0] = 00b(固定的),所以雖然存取的是 43h,但還是寫成40h ! 而要存取到 43h,則從 0cfch+3來達成 (因為: 0cfch&lt;-&gt; 40h,0cfdh&lt;-&gt;41h,0cfeh&lt;-&gt;42h, 0cffh&lt;-&gt;43h)&lt;br /&gt;&lt;br /&gt;3. 基本的PCI device的 config registers可分成 2 parts:&lt;br /&gt;&lt;br /&gt;A. header region(offset 00h~3Fh)&lt;br /&gt;B. device specific region(40h~FFh)&lt;br /&gt;&lt;br /&gt;在BIOS's PCI_SCAN stage中,會touch到 part A. Ex. command byte, BARs, Interrupt line, latency timer,...etc. 而Part B是製作 or design這個device的廠商所附加的 function/feature.&lt;br /&gt;&lt;br /&gt;4. 每個PCI device都可以 request 之前所提的 4 resources:&lt;br /&gt;A. memory resource:透過 Base Address Register(BAR)&lt;br /&gt;B. IO resource:透過 Base Address Register(BAR)&lt;br /&gt;C. Interrupt: 透過 interrupt pin&lt;br /&gt;D. DMA: 這需要 device本身即具有 bus master function(status byte會indicate)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[Why need PCI SCAN]&lt;br /&gt;現在的computer system泰半由許多PCI devices所組成,因此,BIOS POST中另一個重要的 task is : PCI_SCAN !!!&lt;br /&gt;&lt;br /&gt;它代表的是: BIOS會掃瞄 whole system,找出所有的PCI devices; initial them and build a linked list of PCI devices.在此list中的每一個node都代表一個PCI device,且含有其 characteristics !&lt;br /&gt;&lt;br /&gt;Ex. Vendor ID,Device ID, PFA,Option ROM exist or NOT,...etc.&lt;br /&gt;&lt;br /&gt;一旦建好此表,以後的 tasks 隨時都可以參考 !!!&lt;br /&gt;&lt;br /&gt;所以, after PCI_SCAN,有兩件事完成了:&lt;br /&gt;1. PCI device initialization;device config registers(Part A) are correctly set ...&lt;br /&gt;2. One data structure is built to describe the PCI devices in whole system(建在memory中)&lt;br /&gt;&lt;br /&gt;這也是屬於kernel code part ^_^ ( system 一般很少 hang at this stage...)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;符合PCI spec的device即稱為........PCI device ^_^&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[補充] PCIe device&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;PCIe device =&gt; 符合PCIe spec的device(...廢話...)&lt;br /&gt;&lt;br /&gt;對軟體而言,它仍是PCI device. 因此,基本的 header region and device specific region也有. 不過,PCIe新定義了 extended config space,即 offset 100h(含)以上,直到 FFFh( 所以, 最大可以至 4096 bytes )&lt;br /&gt;&lt;br /&gt;存取 PCI config space的方式,用原來 0cf8/0cfc的方式依然可行,但只能 access offset 00h~FFh. 要 access 100h(含)以上的 extended config space,則必須用 memory transaction的方式 !&lt;br /&gt;&lt;br /&gt;Ex. mov ax, [50400000h] &lt;- read device (4,0,0)'s register 0;2 bytes  here 50000000h: PCIe extended base address. 可以從 chipset register得知      bit[27:20]: Bus information      [19:15]: Device information      [14:12]: Function information      [11: 8]: Extended Register      [7:2]: DW number      [1:0]: Byte enable  因此,只要知道 PCIe extended base address,就可以像以前一樣,可以任意存取 PCIe config registers, even &gt; 0FFh !&lt;br /&gt;&lt;br /&gt;除此之外, PCIe device可以由其 Capability pointer(points to a linked list of capabilities)辨認出來. 因為,在眾多的 capabilities中,會有一個 PCIe capability;其 ID value = 10h.&lt;br /&gt;&lt;br /&gt;Note: PCIe extended base address 要 reserve and report to OS. Size is 256MByte. 這是BIOS需要做的. (當然,BIOS也要將此 base address寫入 chipset register,讓 chipset 知道:有這樣的 cycle時,是給PCIe device的 ! )&lt;br /&gt;&lt;br /&gt;[補充] For P2P bridge&lt;br /&gt;&lt;br /&gt;P2P bridge = PCI-to-PCI bridge. 其存在可以 introduce 另一 new PCI bus,可以容納更多的 PCI device.&lt;br /&gt;&lt;br /&gt;P2P bridge亦有其 PCI config space,但是 lauout 與 PCI device有點不同,大家可以參閱P2P spec並與PCI device's config space比較一下.&lt;br /&gt;&lt;br /&gt;在 P2P config space中,我常遇到的 issue是和下列 register有關的:&lt;br /&gt;- Primary bus register: offset 18h&lt;br /&gt;- Secondary bus register: offset 19h&lt;br /&gt;- Subordinate bus register: offset 1Ah&lt;br /&gt;&lt;br /&gt;----------------------------------------&lt;br /&gt;Notes:&lt;br /&gt;這三個 registers是BIOS在 PCI_SCAN時會決定的;所代表的意義是:這個 P2P bridge的上面 PCI bus number is ? 下面的PCI bus number is ? 及包含此 P2P bridge的 "branch" 最深的 PCI bus number is ?&lt;br /&gt;&lt;br /&gt;Ex. 18/19/1Ah of one P2P bridge is 0/2/3&lt;br /&gt;=&gt; 此 P2P bridge 是 "bridge" PCI bus 0 and 2的(橋接在 PCI bus 0 and 2之間);而包含此P2P bridge的 PCI branch(想像成 tree structure) 最大(深)的PCI bus number is 3&lt;br /&gt;----------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- memory base/limit&lt;br /&gt;- IO base/limit&lt;br /&gt;&lt;br /&gt;----------------------------------------&lt;br /&gt;Notes:&lt;br /&gt;這兩個是 BIOS 在 PCI_SCAN時所 assign的. 所代表的是: resource "window" for devices behind this bridge.意即:若P2P bridge下面(就上例言:是 Bus 2上)有 PCI devices,則他們的 BARs 必須被包含在此 window 之內 !!!&lt;br /&gt;----------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[Practice]&lt;br /&gt;[Q]假設有一個 P2P bridge ,下面有一PCI device;現在必須要去 accessPCI device's Device ID/Vendor ID(that is, PCI config read). 但是,問題是:做這事的"點"要在 PCI_SCAN之"前"....那要如何做到呢 ^_^ ?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Ans:假如要在很早前(Ex. PCI SCAN之前)去 access P2P bridge後面的 device,照理是做不到的,因為: P2P bridge沒有被正確的 configed...&lt;br /&gt;&lt;br /&gt;在此例中,P2P bridge的 primary/secondary/subordinate bus要被 set,後面的device才能被 accessed到 !&lt;br /&gt;&lt;br /&gt;所以,假如要在 PCI SCAN前就 access,則BIOS必須手動去 set 此 3 bytes;然後,PCI config access才能被 forward to 其後的 PCI devices...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[Q] 如何 disable memory or IO resource window ?&lt;/strong&gt;&lt;br /&gt;Ans: 只要將 base設成比 limit "大" 即可 !!!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;---------------&lt;br /&gt;-  相關討論 Part1   -&lt;br /&gt;---------------&lt;/strong&gt;&lt;br /&gt;前輩已經提到P2P Bridge我就直接問我的問題了&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[Q1] Bridge 是用來擴充PCI Bus，在PCI Bus Spec與PCI-PCI Bridge Spec中定義，PCI Device是透過IDSEL來決定他的身分，其中PCI Bus Spec定義AD[31:11]，而PCI Bridge Spec定義AD[31:16] 當做IDSEL，這中間差異為何? 為什麼一個要從Bit 11開始當作是Dev 0 ，而另一個由Bit 16 才當作是 Dev 0 ?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Ans: 1. IDSEL對PCI device而言是 input,是用來當作 device's "chip-select"訊號. 而且,IDSEL "如何連接" 是 H/W決定的,BIOS無法決定.&lt;br /&gt;&lt;br /&gt;假如將板子上某個device's IDSEL "割斷",則此 device將無法接受 PCI configuration read/write(以 ru.exe來說,就是按F6後,是看不到它的...)&lt;br /&gt;&lt;br /&gt;那要如何決定 device's IDSEL ? 一般而言, board designer會將 "unused AD lines"拿來做 IDSEL,以連接至 PCI device.&lt;br /&gt;&lt;br /&gt;在 configuration access時,所下的 Ex. "o cf8 80001020"(看起來是 I/O transaction)會被 host bridge轉成 configuration transaction;此時, host bridge即可判斷此 transaction 要 access的 device是否在該 PCI bus上;if YES 轉成 Type 0 transaction;If NO 轉成 Type 1 transaction,並往下發送...(host bridge只要 check latched "bus information"即可完成此判斷 !)&lt;br /&gt;&lt;br /&gt;以 Type 0言,AD bus上的 format as follows:&lt;br /&gt;bit[1:0] = 00 ( indicates "Type 0" )&lt;br /&gt;bit[7:2] indicates register number&lt;br /&gt;bit[10:8] indicates function number&lt;br /&gt;&lt;br /&gt;那 Bus number ? Device number ?&lt;br /&gt;=&gt; Bus number不必知道 ! 因為:Type 0產生即代表 bus number = 現在的 bus #&lt;br /&gt;=&gt; Device number呢 ? 因為,此時(Config transaction &amp;amp;&amp;amp; address phase) AD bus bit[31:11]沒人用 !!! 因此, board designer會把此 21 bits拿來做 IDSEL用 !&lt;br /&gt;&lt;br /&gt;因此, AD bus bit11 &lt;-&gt; device 0&lt;br /&gt;    12 &lt;-&gt; device 1&lt;br /&gt;    .......&lt;br /&gt;&lt;br /&gt;當然,不可能 21 bits都拿來接 PCI devices;因為電路上的現實考量...&lt;br /&gt;&lt;br /&gt;.................以上為:我所知為何從 bit11開始來當作 IDSEL................&lt;br /&gt;&lt;br /&gt;以 Type 1言,PCI-PCI bridge收到後,會將其 bus information與自己的 secondary bus number比較;若是 addressed device是在 secondary bus上,則將 Type 1 -&gt; Type 0;若否,繼續包成Type 1往下一層送...&lt;br /&gt;&lt;br /&gt;在P2P spec v1.1 page 22 有一張表,說明 IDSEL generation(from primary address -&gt; secondary address),其中有提到: if primary address bit[15:11] =0,則 secondary address AD [31:16] = 0000 0000 0000 0001;以此類推.&lt;br /&gt;&lt;br /&gt;所以,我覺得為什麼 for P2P bridge 其 IDSEL可由 bit[31:16] 來決定的原因在此 !!!(表的關係...)&lt;br /&gt;&lt;br /&gt;.................以上為:我推論為何從 bit16開始來當作 IDSEL................&lt;br /&gt;[補充]&lt;br /&gt;PCI config index register裡面的資料其實和硬體解出configuration cycle是相關的.&lt;br /&gt;一.轉換出來是type 0 cycle的話. 硬體只要做以下兩件事.&lt;br /&gt; 1. mask 掉bus number(bit 16 ~ 31)以上的部份.&lt;br /&gt; 2.解碼 device number的部份即可到對應的 AD bit. 所以其最低可以使用的就是AD11.也就是說一個bus上最多只能有 21個 devices(只是由於推動力問題, 往往是做不到的).&lt;br /&gt; Note:其實也可以設計成其他大於AD 11開始, 這要看chip設計者決定了.&lt;br /&gt;二. 轉換出來是type 1 cycle的話. 只要做&lt;br /&gt;1. mask 掉reserved以上的部份(bit 24 ~31)&lt;br /&gt;2. bit 0 = 1&lt;br /&gt;由於P2P跟其他device不同的地方就是, 除了type 0 clcye以外, 還必須處理 type 1 cycle. 這也是分成兩部份&lt;br /&gt;一. type 1 -&gt; type 0. 當 bus number 等於 secondary bus number 時候出現.&lt;br /&gt;1. 解碼 device number 到對應的 AD. spec中有提到轉換的表. dev 0 = AD16....etc&lt;br /&gt;2. 把 bit 0 由1 變成 0&lt;br /&gt;二. type 1-&gt; type 1. 當 bus number 介於 secondary bus number和 subordinate bus number&lt;br /&gt;1. 直接往下一層送即可.交給其他的P2P 處理.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[Q2] 在IA32下，CONFIG_ADDRESS 會被轉成Configuration Cycles，當Bus Number &lt;&gt;0 時，NB會轉成Type 1 然後往 DMI送到SB，當P2P Bridge收到後，然後定址到Slot上面的PCI Device，這樣說法對嗎?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Ans: 總而言之, 是自己local bus上的,就會轉成 Type 0,然後打在AD bus上,等待認領;若否就轉成 Type 1,往下一個bridge送,繼續尋找...對的人...for each bridge,都是一樣...&lt;br /&gt;[補充]&lt;br /&gt;對 PCI spec是, 如果以Intel PCI express架構來說. 那個已經被封裝成 pci express的 package了.沒有所謂的 type 0, type 1 cycle了.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[Q3]PCI Device透過IDSEL來決定身分，那PCIE Device呢? 我查過資料，好像PCIE不需要IDSEL那他是如何決定Device Number ?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Ans: 我所遇的 PCIe device也是由 AD bit[31:11]中找線拉至 device's IDSEL決定的.不知其他家 chipset是如何 implement.&lt;br /&gt;[補充]&lt;br /&gt;PCI express 是internal routing. PCI express是個跟PCI 完全不同的架構. 只是為了軟體相容性的關係, 把software架構做的跟PCI bus一樣. PCI express是point-to-point架構, 一個link 只會連接一個device. 跟PCI 這種可以多個device在同一bus上是不一樣的. 所以 device number對PCI express是完全不重要的.&lt;br /&gt;Note. AMD的Hyper transport 也是基於一樣的心態來設計軟體架構的.&lt;br /&gt;&lt;br /&gt;※ PCIe 的device是 internal routing. 以規格來看,下一層的 device number都是為0.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;------------------&lt;br /&gt;- 相關討論 Part 2 -&lt;br /&gt;------------------&lt;/strong&gt;&lt;br /&gt;DMI指的是 Intel 南北橋中間的通道 ! 之前也是不知P2P bridge部份關於IDSEL的配置,查了表才知道原來有這樣的 mapping(primary address&lt;-&gt;secondary address). 其實,可以說 "unused AD bus 會被拿來當 IDSEL用"就是了吧 ^_^&lt;br /&gt;&lt;strong&gt;[補充]&lt;br /&gt;是的, 只要軟體能夠知道routing 關係.怎麼接都可以. 只要bus controller控好實際的IDSEL即可. P2P之所以會有嚴格規定(兩項, 1. IDSEL&amp;amp;device number表, 2. secondary bus IRQ routing)是因為P2P 不一定是在板子上. 包含卡都可以有P2P bridge. 在板子上的P2P 可以靠BIOS來建立正確的 routing, 但是插卡不行. 所以必須把這些定義好. 這樣 PnP software(BIOS or OS)才能正確的完成IRQ 分配.讓卡正常工作. 所以如果觀察某些板廠. 就算是真的p2p 沒有存在在板子上, 很多PCI slot的IRQ routing都是依據p2p spec裡面的規定做(因為SB的PCI bus還是落在P2P之後).&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;在 PCI scan時,BIOS會掃描整個系統的PCI architecture(包含 device &amp;amp; bridge);其掃描方式由BIOS's PCI kernel來決定 !&lt;br /&gt;&lt;strong&gt;[補充]&lt;br /&gt;其實了解PCI spec. 要寫PCI scan其實可以效率好又正確. 常見的新進工程師寫法大概就是 3個 loop來處理. bus:0~255, device:0~31, function:0~7. 掃個 256*32*8次, 反正都是程式做, 結果往往也看來正確.這種寫法其實是不對的. (其實,若是多了解硬體的架構,就可以寫出有效率的code了 ! 這也是F/W工程師的價值...)&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Ex. Assume 系統架構是這樣的: NB,P2Px3, PCIe bridge x2;其中:&lt;br /&gt;A. 3 P2Ps的配置 is: P2P0下面接P2P1;P2P下面接P2P2&lt;br /&gt;B. PCIe x 2 &amp;amp; P2P0都在 bus 0;其PFA為&lt;br /&gt;    NB(0,0,0)&lt;br /&gt;   P2P0(0,1,0)&lt;br /&gt;   PCIE0(0,4,0)&lt;br /&gt;   PCIE1(0,5,0)&lt;br /&gt;&lt;br /&gt;=&gt; 最後的 PCI achitecture is:&lt;br /&gt;&lt;br /&gt;Bus 0----------------------&lt;br /&gt;    NB(0,0,0),P2P0(0,1,0),PCIE0(0,5,0),PCIE1(0,6,0)&lt;br /&gt;&lt;br /&gt;*下面 Bus 1/2/3由 P2P0/1/2所 introduce:&lt;br /&gt;Bus 1----------------------&lt;br /&gt;    P2P1(1,0,0)&lt;br /&gt;Bus 2----------------------&lt;br /&gt;    P2P2(2,0,0)&lt;br /&gt;Bus 3----------------------&lt;br /&gt;&lt;br /&gt;*下面 Bus 4由 PCIE0所 introduce:&lt;br /&gt;Bus 4----------------------&lt;br /&gt;&lt;br /&gt;*下面 Bus 5由 PCIE1所 introduce:&lt;br /&gt;Bus 5----------------------&lt;br /&gt;&lt;br /&gt;所以,Bus number 是由BIOS's scanning "algorithm"所決定的;假如採用 depth-first,則會產生上述的結果 ! 決定後的值會填到 bridge的 Primary/secondary/subordinate bus number registers !&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[Q]順便問個問題好了. 其實function number不應該是永遠需要scan的, 為什麼?什麼時候才需要scan function number?&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Ans: 我想,對於 function number的問題,應該是: PCI header region offset 0Eh bit7代表: milti-function or NOT ! 因此,可以先 check此bit,再決定要不要往下掃了...這樣又少做了許多虛工...^_^&lt;br /&gt;&lt;br /&gt;Ex. PFA (0,3,0) 有回應(that is, Vendor ID/Device ID != 0xFFFFFFFF),則先check (0,3,0)'s PCI Reg0Eh bit7; if "1" then 此device為 multi-function device,還要再往下找 Ex. (0,3,1~7) 有無回應;if "0" then try next device number...!&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;br /&gt;[補充，加快速的的方式]&lt;br /&gt;檢查multi function bit是正確的, 但是不只是因為效率問題. 而是PCI 規格中, single function裝置可以不解碼 config cycle type 0 bit[8~10], 也就是說 一個 single function裝置, 會對 所有的function number回應, 也就是會出現 8 個相同的device.&lt;br /&gt;&lt;br /&gt;順便說一下我的scan加速法. 其實我不是使用 vandor ID &amp;amp; device ID來判斷裝置存在與否. 我是用 class/subclass/interfae ID來作判斷. default 只scan bus 0, 遇到 P2P bridge才會把taget bus number+1, 如果遇到multi host(host bridge 數量&gt; 1)的板子才會完整掃描 255個 bus. ^_^&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------------------------&lt;br /&gt;---------------------------------------------------------------------------------&lt;br /&gt;---------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;~轉貼自艾克索夫實驗室~&lt;br /&gt;Rootkit in PCI Option ROM&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;「Rootkit」一字來自 UNIX 界；但目前通常用於描述 Windows 木馬程式作者所運用的隱形技術。&lt;br /&gt;起初，Rootkit指的是一組程式，可讓駭客躲過偵測。 為達成此目的，可執行的系統檔案 (如 login、ps、ls、netstat 等) 或系統程式庫 (libproc.a) 會遭到更換，或安裝核心模組。 這兩種動作只有一個相同目的；防止使用者收到正確資訊，知道電腦上發生了什麼事。&lt;br /&gt;&lt;br /&gt;首先介紹PCI的基本常識, PCI Bus是在約1990年由Intel發展出來, 用來連接主機板上的各項裝置的匯流排標準, 後來成為業界的標準之一, Spec可以在PCI-SIG註冊會員之後下載, 架構上簡單的說, 就是一個Host bridge, 在一般的PC上通常指的就是North Brdige, 這個brdige後面就是bus#0(當然也有Multi Host-Bridge的狀況, 這邊舉例的是最單純的情況), 然後接到South Bridge, South Bridge之後可能接的是ISA Bus, IDE Controller, USB, IDE, DMA Controller等等, 如果bus#0上還有別的PCI Bridge, 這個Bridge後面就是bus#1, 如果有多個Bridge存在(PCI最多可以有256個bus), bus#就不一定是固定的了, 一個PCI Bus上可以有32個device, 每個device可以有8個function, 每個function都有屬於自己的256個register. 在PCI的規範裡, 256個register中的前0×40個是公定的功能, 從0×40到0xff則由各家廠商自行實作, 存取這些register的方法, 一般的PC上是透過IO port 0xCF8~0xCFF, 如果是新的PCI-Express則是直接透過Memory Mapped IO, 以存取記憶體的方式直接進行存取, 例如我們想要讀取一個在bus#0 dev#1 func#0的register#40~43, 透過IO的方式如下:&lt;br /&gt;&lt;br /&gt;mov eax, (0x01 &lt;&lt;&gt;mem decode), Command Register(0×04~0×05)的Memory Space Bit打開, 在0xFE000000的地方你就可以找到這個rom, 開頭是0×55AA(這當然也是規範之一, 用來辨視是否為一個PCI rom), BIOS在POST過程中, 會逐一掃描位於主機板上所有的PCI Device, 假如device上有rom, 就會把它給拷貝到memory中, 然後用jmp指令跳到ROM開頭offset 0×02(別忘了開頭offset 0×00是0×55AA)的地方開始執行PCI ROM, 執行完後ROM會再把控制權交回到BIOS手上, 一般而言, 在傳統記體空間中, 0xC0000~0xCFFFF是給VGA ROM用的, 0xD0000~0xEFFFF則是留給一般的PCI ROM使用, 當然各種情況下還是會有些許差異, 例如有些BIOS會保留0xE0000~0xFFFFF給自己使用, 像是BIOS的interrupt service, DMI data….等等雜七雜八的東西, 執行完的ROM仍然會保留在記憶體中, 因為有些ROM會修改IVT(Interrupt Vector Table), 將某些interrupt service導向自己的code, 像是VGA ROM可能就會hook int 0×10, 這是很合理的, 因為int 0×10是BIOS所提供用來控制螢幕的service, 聰明的你看到這裡應該就知道前面所提的那篇文章想說什麼了, 如果有個”惡意”的程式被埋在PCI ROM裡面, 只要一開機就會自動被執行, 它的運作並不是一時的, 它可以hook某個OS一定會用到的BIOS Interrupt Service, 然後在這個interrupt service被呼叫的時候動作就可以了, 而且麻煩的是即使你format你的HDD也沒用, 除非你把有問題的PCI Device從你的主機板上移除, 嗯….聽起來蠻炫的, 但是, 有可能嗎?&lt;br /&gt;&lt;br /&gt;要回答這個問題之前, 需要知道一些基本的常識, 在保護模式下, 因為IO動作受到限制的關係, 要存取IO並不像在DOS那樣容易, 但如果想嘗試Re-flash一顆PCI ROM, 勢必得進行IO動作, 所幸在Windows下這並不是不可能的事, 有些人可能知道利用SeTcbPrivilege和使用ProcessUserModeIOPL structure呼叫undocumented Native API NtSetInformationProcess()就可以達成目的. 一旦攻擊者有辦法修改PCI ROM, 他就可以利用文章中所提到的例子: int 0×10(Windows在開機過程中會透過Ke386CallBios()呼叫int x010), 作他想作的任何事了.&lt;br /&gt;&lt;br /&gt;可惜不論哪種攻擊方式, 最終都是要對OS kernel動手腳, 利用各種偵測工具(如: Archon Scanner), 一定可以找到有問題的地方, 如果最後的箭頭指向PCI ROM, 我們可以透過上文所述, 將存在PCI Device和memory中的ROM給dump出來, 需要dump兩邊的rom, 是因為PCI Spec規範中允許實際上所需要配置的記憶體不一定要等於原本rom的大小, 藉以節省保貴的記憶體(別忘了PCI ROM只能被配置到幾個64KB的segment裡而已), 然後向PCI Device的製造商索取正常版本的rom進行比對, 藉以得知是否為被修改的版本. 假如發現有不一樣的地方, 接下來可以朝幾個方向繼續分析是否為有問題的ROM, 我們可以檢查一下它是否修改了不必要的IVT, 像PXE ROM就不太可能hook int 0×10, 或是有保護模式相關的程式碼, 因為一般的ROM應該都是在real mode下執行, 所以應該不會切到protected mode, 如果有相關的程式碼那就非常可疑, 還有rom裡面是否有可疑的字串, 或是位在Windows Kernel位址空間裡的32-bit address, 另外ROM裡面也不太可能出現編碼過的code, 如果rom裡的code很難被disassemble, 或是充滿了一堆obfuscated code, 那也是很有問題.&lt;br /&gt;&lt;br /&gt;除了軟體的方式, 最近興起的新技術TPM也能克制這種攻擊手法&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-6154036058327693281?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/6154036058327693281/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=6154036058327693281' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/6154036058327693281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/6154036058327693281'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/06/bios-for-pci.html' title='BIOS for PCI'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-3914789634547886086</id><published>2008-06-27T20:53:00.000-07:00</published><updated>2008-06-27T21:19:34.049-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/Firmware'/><title type='text'>打造自己的BIOS</title><content type='html'>(轉貼於"小華的部落格http://biosengineer.blogspot.com/")&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);font-size:180%;" &gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;第一集：&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;存放BIOS的設備從早期都放在EEPROM到現在的Flash ROM，一路上的演變已經可以寫成一部BIOS歷史課本。&lt;br /&gt;&lt;br /&gt;在早期的BIOS中，BIOS本身程式碼就是用來當成一個Boot Loader，但是由於後來的晶片功能越來越強大且BIOS除了初始化硬體設備之外還要協助OS去支援一些功能，所以整個BIOS程式碼就已經變成了一個 龐然大物，而維護整個BIOS程式碼也非一個人的能力所及。&lt;br /&gt;&lt;br /&gt;因此後來的BIOS程式碼都是由一些BIOS供應商來負責維護，各家BIOS供應商會有自己的撰寫方式與架構。正因為如此，開發BIOS的程式碼目前也都是使用各家廠商所提供的開發環境來建構。&lt;br /&gt;&lt;br /&gt;而這篇文章的目的在於如何在目前的PC架構下純手工打造一個屬於自己的BIOS環境以及撰寫一個簡單的BIOS程式碼可以讓系統輸出一個值到Port 80h，我同事問我為什麼不寫一個mini BIOS可以開到DOS下去，因為如同我上述所說，寫是可以寫啦，要花很多的精力跟體力，這邊只是拋磚引玉說一個大概，然後描述一下如果自己真的要撰寫一 個BIOS 要如何做? 或許有些人有興趣可以找幾個朋友一起寫BIOS，或許哪一天就可以開ㄧ家台灣BIOS供應商...(呵呵，我自己在幻想啦!)&lt;br /&gt;&lt;br /&gt;需要用到的工具以及相關知識：&lt;br /&gt;1.MASM 6.15&lt;br /&gt;2.Turbo C++ 3.0&lt;br /&gt;3.基本組合語言撰寫能力&lt;br /&gt;4.基本C語言撰寫能力&lt;br /&gt;5.IA32 Spec vol 1~3&lt;br /&gt;6.EC BIOS ROM(可以請EC BIOS Eng協助)&lt;br /&gt;&lt;br /&gt;實驗目的與方法:&lt;br /&gt;1. 建立一個BIOS 開發環境&lt;br /&gt;2. 建立一個1MB BIOS ROM file&lt;br /&gt;3. 利用組合語言撰寫一個64kb 大小的BIOS程式碼的 binary file&lt;br /&gt;4. 利用C語言撰寫一個Build Tools，並將EC與64k BIOS塞進去1MB BIOS ROM&lt;br /&gt;5.利用燒入器將1MB BIOS ROM燒入到MLB中，並且上電後檢查Port 80h是否有正確的輸出我們程式碼中撰寫的值。&lt;br /&gt;&lt;br /&gt;上面的程式撰寫部分不需要很強的能力，只要基本的C或是組合語言語法就可以了，所以算是基本入門，重點還是在我ㄧ直強調的地方 "懂架構才是重點，程式語言只是工具而已"...。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);font-size:180%;" &gt;&lt;span style="font-weight: bold;"&gt;第二集：&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;電腦發展至今已經經過了很長的時間，許多遇到的問題也都被ㄧ些前輩解決了，因此目前學校或是市面上的書籍幾乎都是講解如何在一個"現成且成熟"的平台上發展。&lt;br /&gt;&lt;br /&gt;例如很多書會教你寫VC/.net/Java ，但是，說到如何去寫編譯器、作業系統及開發BIOS的書就不多了，也因此大家比較專注於如何在成熟的平台上能夠快速/有效率/有系統性的開發以及提出解 決問題的辦法，而像我因為興趣而去探討BIOS的本質的人就應該比較少吧，畢竟這些問題在之前的前輩都已經遭遇過，也提出了很好的解決方式，所以才會有目 前一些實力堅強的BIOS 供應商的存在，因此也沒必要像我這樣純手工打造。&lt;br /&gt;&lt;br /&gt;在前ㄧ篇的文章中我已經大致上描述了一下我的實驗方式，這邊就針對整個流程作ㄧ些詳細的介紹。&lt;br /&gt;&lt;br /&gt;在純手工打造你自己的x86 BIOS(1) 中有提到，你可以學習到的東西是比較基本的概念，所以我並不會把完整的Sample code貼上來，畢竟教釣魚比給魚吃還重要，因此請大家輕鬆看待我的拙作(小弟也只入行1年多 ，還請前輩還多多指導)。&lt;br /&gt;&lt;br /&gt;前一篇文章中所提到的核心部份在於我撰寫了64K 的BIOS程式碼 (MyBIOS.asm)，實際不到64k ，只是我利用了填00h的方式填滿到64k。&lt;br /&gt;&lt;br /&gt;而組譯與連結是透過ML.EXE ，輸出的是一個MyBIOS.exe ，而這個是一個DOS下的執行檔，所以裡面有MZ Header ，因為被多加了這個Header 因此MyBIOS.exe約65k ，而我會再利用Build tools取出裡面的64k ，然後變成MyBios.bin，當然這只是最簡單的方法而已，但不是唯一。&lt;br /&gt;&lt;br /&gt;[註] EXE2BIN 只能轉換小於64k 的檔案，所以這邊不能使用它，所以我才自己轉換。&lt;br /&gt;&lt;br /&gt;&lt;img id="BLOGGER_PHOTO_ID_5137722484842682210" style="margin: 0px auto 10px; display: block; text-align: center;" alt="" src="http://bp0.blogger.com/_vBuwAqY3NeM/R0zbYQ-V12I/AAAAAAAAACM/XcNUQ_h0ZeM/s400/BIOS.GIF" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;當取出了MyBios.bin 之後連同EC.bin 經由Build.exe 產生一個1MB 大小的BIOS ROM Image file，然後把位置固定住。&lt;br /&gt;&lt;br /&gt;固定位址是因為：&lt;br /&gt;1. 我的範例中的Platform 上面的EC Controller是採用Share ROM方式，也就是把EC BIOS包在System BIOS中，因此我們需要固定住位址，這樣子EC Controller 才能去System BIOS中讀取EC BIOS的程式碼並且執行。&lt;br /&gt;&lt;br /&gt;2.由於x86 CPU讀取第一條指令是在 FFFF_FFF0h，所以我們必須要把BIOS code固定在尾端往下算的64k 範圍內，如下圖所示：&lt;br /&gt;&lt;p&gt;&lt;img id="BLOGGER_PHOTO_ID_5137722557857126258" style="margin: 0px auto 10px; display: block; text-align: center;" alt="" src="http://bp1.blogger.com/_vBuwAqY3NeM/R0zbcg-V13I/AAAAAAAAACU/uVcIfyt_ovU/s400/1MB.GIF" border="0" /&gt;圖 中可以看到整個BIOS ROM Image file是1MB ，其中64k是EC code另外64k是BIOS code，然後擺放在1MB 檔案中的位置就如上圖所示，其餘空白的地方我都是填00h/ffh (須看BIOS ROM Spec中說明空白是00h/ffh)&lt;/p&gt;&lt;p&gt;總結:&lt;/p&gt;&lt;p&gt;●MyBios.asm 負責CPU 第一條指令以及組態CPU 模式還有設定Port 80h的輸出並且輸出一個99h 到Port 80h&lt;/p&gt;&lt;p&gt;●EC.bin EC的BIOS Code，由EC BIOS工程師撰寫，我只是拿來用而已&lt;/p&gt;&lt;p&gt;●Build.exe 會先產生一個1MB 空白的BIOS ROM Image，然後把上面兩個bin file塞到先前產生的1MB 空白BIOS ROM Image，並固定其擺放位址，而擺放時並沒有考慮任何File System的架構問題，而是直接塞。&lt;/p&gt;&lt;p&gt;●MyBIOS.ROM 產生出的MyBIOS.ROM就是要用來燒入到BIOS part中的檔案，也就是類似一般大家在Flash BIOS時的那個檔案。&lt;/p&gt;&lt;p&gt;C:\&gt; Flash.exe /all MyBIOS.ROM&lt;/p&gt;&lt;p&gt;上面是一般大家使用某個Flash Utiltity 時會打的一些指令，因為工具不同所以參數也不同，不過相同的是都會有一個BIOS ROM Image file(例如MyBios.ROM)&lt;/p&gt;&lt;p&gt;另 外這邊有點不ㄧ樣的地方在於我沒有自己寫Flash Utility(我們BIOS裝在EC Controller下，而我又懶的看EC Spec)，所以沒辦法像上面方式使用某個工具去更新 BIOS ROM，況且你們如果要實驗相同的東西，Flash Utiltiy也不能共用，所以這部份有興趣的人就自己研究一下你們公司內是怎樣撰寫這部份的工具。&lt;/p&gt;&lt;p&gt;而我的燒錄方式是採用EC Controller提供的燒入器，所以直接點選我的MyBios.ROM就可以燒進去BIOS Part了，而這部份也不多做說明。&lt;/p&gt;&lt;p&gt;由於整個實驗我才花了1.5天時間(0.5天寫Build.exe + 1天寫MyBios.asm)，所以很多地方沒考慮進去，希望各位有其他意見請告訴我，謝謝!&lt;/p&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);font-size:180%;" &gt;&lt;span style="font-weight: bold;"&gt;第三集：&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;在前面兩篇文章中的描述中其實大家就應該可以知道我的實驗環境由幾個部份所組成，所以我這邊假設 "如果我是ㄧ個BIOS Vendor"，我將會如何描述我前面所說的那些部分。&lt;br /&gt;&lt;br /&gt;在我的實驗中，整個BIOS Build Environment 我們可以得知如同下圖的架構，我在後面將分別對這些部份做ㄧ個簡單的說明。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bp1.blogger.com/_vBuwAqY3NeM/R04TJA-V14I/AAAAAAAAACc/I4HIxv5xBCQ/s1600-h/Build.GIF"&gt;&lt;img id="BLOGGER_PHOTO_ID_5138065270477543298" style="margin: 0px auto 10px; display: block; text-align: center;" alt="" src="http://bp1.blogger.com/_vBuwAqY3NeM/R04TJA-V14I/AAAAAAAAACc/I4HIxv5xBCQ/s400/Build.GIF" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;1.Source code : 這就是我的MyBios.asm，只有一個檔案，ㄧ般我會放在某個目錄內，大家可以想一下如果擴充成7000多個檔案的時候，你會放同一個目錄嗎? 如果分類你要如何分? 如果修改,你要直接改嗎? 還是採用什麼方式去覆蓋?&lt;br /&gt;&lt;br /&gt;2. Build Settings :  我使用的是MASM，而他在我的C:\MASM，假如你是利用makefile產生結果，那麼你就會需要設定一些工具的路徑，組譯或是編譯的程式是哪ㄧ個，參數為何...等。&lt;br /&gt;&lt;br /&gt;3.Build Tools : 像我提到的Build.exe就是我自己寫的，用來輔助建立BIOS Image時所使用，所以當你的環境越來越大的時候，所使用的Tools可能就不只一個。&lt;br /&gt;&lt;br /&gt;4.Build : 當上面的部分都結合在一起後，就可以產生出結果，ㄧ般我們可以利用makefile 方式把上面步驟都結合在一起，然後就可以方便的產生出結果。&lt;br /&gt;&lt;br /&gt;5.BIOS Image : 在我的實驗中，產生的結果就是MyBIOS.ROM。&lt;br /&gt;&lt;br /&gt;結論：&lt;br /&gt;實驗中大家可以發現，其實BIOS vendor所提供的環境基本的本質很簡單，只是當你在實做的時候你會遇到一些問題，而你在解決這些問題的時候不知不覺整個架構就會越來越複雜，因此當我 們接觸到一個成熟的BIOS Build environment時，就會需要了解更多的東西以便我們更能夠駕馭BIOS vendor所提供的環境。&lt;br /&gt;&lt;br /&gt;前面這幾篇文章大致上描述出BIOS Build Environment的基本架構，所以當你想要寫一個BIOS然後提供給別人一個環境去撰寫BIOS時，其基本本質大概就是這樣，後面的文章中我會繼續 介紹實際上MyBIOS.asm 中我們該撰寫什麼後我們才能夠在Port 80h 的7段顯示器上顯示99h。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);font-size:180%;" &gt;&lt;span style="font-weight: bold;"&gt;第四集：&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;上ㄧ篇文章我已經針對我的實驗做了敘述，這裡我就針對實際上我的程式碼撰寫的內容做一個介紹。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;在程式碼的撰寫中，其實我只有使用了簡單的C語言跟組合語言語法，重點是要讓大家知道， 其實BIOS跟一般的Boot Loader寫法沒什麼不同，只是PC上面的BIOS需要考慮的事情比一般的Boot Loader還多很多，因此程式碼 size可以大 到1MB甚至是2MB (ㄧ般Boot Loader不可能這麼大)，所以我有機會玩一個這麼大的Boot Loader也真是很榮幸的啦!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;廢話不多說，我就先針對我前面提到的Build.exe 內的程式碼說明；&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;底下是我的Build.c 內的程式碼片段，其實我就只有使用到fopen() 、fputc() ...等基本的函數去讀寫一個檔案，所以可以很容易的把我組譯好的MyBIOS.bin 跟EC.bin 塞進去同一個檔案內，做法其實很簡單，就是像我下面做法一樣，先利用fopen()開啟檔案，然後在把你要的資料寫進去檔案，只是寫的時候你要考慮 file offset 位置的問題，因為當你燒錄到BIOS part中的時候，CPU是會固定重FFFF_FFF0h的位址讀取第一條指令，因此你要像我前面說的一樣，把MyBios.bin放在固定的位址中。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;//建立一個空白的MyBIOS.ROM , 裡面資料都是00h&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;void show_help(void)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;  printf("Build.exe v1.0.0   by Harrison Hsieh \n"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;  printf("===========================================\n"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;  printf("/C Init MyBIOS.ROM \n"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;  printf("/B [EC] [BIOS]    Add  Rom \n"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;  printf("Output : MyBios.ROM \n");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;}&lt;br /&gt;void InitBiosROM(char *argv[])&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;   FILE *fo; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;   long i; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;   if ((fo = fopen (BiosRom, "wb")) == (FILE *) NULL) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;    {     &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;       exit(1); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;for(i=0 ; i&lt;= BIOSSIZE ; i++)  //1MB &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;{  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;    fputc(0x00,fo); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;/* All done, close the file */&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt; fclose (fo);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;在說明完Build.c內的做法後，接著說明MyBIOS.bin 內的程式碼撰寫；&lt;/span&gt;&lt;br /&gt;其實在MyBios.asm 中，我只有做4 件事情：&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;1. 設定好FFFF_FFF0h的第一條指令&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;2.開啟BigReal Mode (因為我要設定ICH9的RCRB內的暫存器，所以要開啟)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;3.設定ICH9內的暫存器，把所有Port 80h的訊號轉送到LPC介面(我的Post card走LPC界面，所以要設定)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;4.輸出99h 到Port 80h(所以LPC介面上面的Post card就會顯示99h)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;底下是我的MyBIOS.asm 內的程式碼片段：&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;COLDBOOT:        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                      CLI &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ;; 1. Enable big real mode&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     JMPREG  di,Make4GBSegmentDI  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ;; 2. Set RCRB base address&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ;;  3. Config ICH9 Register  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ;; 4. Out 99h to Port 80h&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                    .... &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     mov     dx, 0cfch                                    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     mov     eax,RCRB_BaseAddr&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     out     dx, eax&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                    ....       &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                 &lt;/span&gt;&lt;span style="font-size:78%;"&gt;   and     BYTE PTR es:[esi], NOT (04h) ; RCRB+xxxxh bit 2=0  Output to LPC&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                    ....&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;fPostCode:        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                   mov     al,099h      &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                   mov     dx,80h       &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                  out     dx,al       &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                    jmp     fPostCode&lt;/span&gt;   &lt;span style="font-size:78%;"&gt;;無窮回圈ㄧ直顯示99h&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ... &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     wbinvd        ;  ...begins here on power up&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     PUBLIC  POWER                           &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;POWER:                     &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                      JMP COLDBOOT   ; first jump   &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;                     DB '11/14/07',00,00,00  ; My release marker&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;以上就是我撰寫的程式碼內容的說明，其實沒有用到什麼特別的東西，如果說比較難的部份大概就是如何把程式碼塞到正確的位址吧。&lt;br /&gt;&lt;br /&gt;總結：&lt;br /&gt;純手工打造你自己的x86 BIOS 文章(1)~(4) 在這邊就做一個結束，在這幾篇文章中的實驗我主要是要幫助剛入門的BIOS新手去了解整個BIOS vendor提供的BIOS環境架構以及實際上BIOS code撰寫的第一步，因為很多東西都是入門的第一步比較難。&lt;br /&gt;&lt;br /&gt;還記得ㄧ年前我剛入行的時候，我們學長跟我說寫BIOS最簡單的方式就是自己把一個BIOS寫到能開機你大概就已經學會了，雖然我離能自己寫到開機還有一 段距離，不過在學習的過程中也學到了很多東西，因此當初會想自己純手工寫一個能讓x86 CPU執行一段BIOS code的環境也是希望能幫助更多BIOS入門時遇到挫折的朋友 ^^Y。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-3914789634547886086?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/3914789634547886086/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=3914789634547886086' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3914789634547886086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3914789634547886086'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/06/bios_27.html' title='打造自己的BIOS'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_vBuwAqY3NeM/R0zbYQ-V12I/AAAAAAAAACM/XcNUQ_h0ZeM/s72-c/BIOS.GIF' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-2552065237935405545</id><published>2008-06-27T20:52:00.001-07:00</published><updated>2008-06-27T21:19:17.941-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/Firmware'/><title type='text'>BIOS開發</title><content type='html'>&lt;h3 class="post-title entry-title"&gt; &lt;/h3&gt;  &lt;div class="post-body entry-content"&gt; (轉貼於"小華的部落格http://biosengineer.blogspot.com/")&lt;br /&gt;&lt;br /&gt;這篇文章主要是概述 BIOS 開發環境下的一些基礎知識，有助於了解如何自己去撰寫一個屬於你自己的 BIOS。&lt;br /&gt;&lt;br /&gt;大家都知道Legacy BIOS是使用Assembly 所撰寫，目前的UEFI則是使用C語言，但是不論是哪一種BIOS，其開發環境下的基礎知識都還是相同。&lt;br /&gt;&lt;br /&gt;ㄧ般BIOS工程師開始學習BIOS Vendor所提供的BIOS Code時，最主要會學習下列幾個項目：&lt;br /&gt;&lt;br /&gt;1.Build process : BIOS ROM是如何產生，這部份要去了解的是整個流程為何?&lt;br /&gt;例如: (ㄧ堆Source code) --&gt; 經過哪些Build process --&gt; (產生BIOS.ROM)&lt;br /&gt;&lt;br /&gt;2.Directory : BIOS Code的目錄架構為何? 哪些是屬於Framework/Kernel/Oem ?&lt;br /&gt;&lt;br /&gt;3.Build Config : BIOS 相關參數的設定，每家Vendor設定方式都不同!&lt;br /&gt;&lt;br /&gt;4.Build Tools : BIOS 建立時使用了哪些工具，ㄧ般都是MASM+VisualStudio+DDK+Bios Vendor自己開發的一些Tools。&lt;br /&gt;&lt;br /&gt;5.Build your BIOS ROM : 如何建立你的第一個BIOS ROM，ㄧ般都是使用nmake/直接在IDE(整合開發環境下)下設定好，就可以直接去Buildㄧ個完整的BIOS ROM。&lt;br /&gt;&lt;br /&gt;有了上述的整理分類，其實不難發現，實際上我們撰寫的BIOS code只是一個BIOS Vendor做出來的環境下(或稱為框架下)去"填寫"一些屬於我們的程式碼，就像是C語言的開發環境下你只需要知道在main(){.....} 的括號內去撰寫程式碼就好了，後面的事情BIOS Vendor都幫你做好了。&lt;br /&gt;&lt;br /&gt;所以OEM/ODM端的BIOS能夠處理的東西都是比較偏向客戶端的需求而去撰寫一些程式碼，我們稱這些程式碼為"Features"。而這些部份就像你買Asus /Acer/...etc 不同家的電腦，裡面所能提供的功能會不同。&lt;br /&gt;&lt;br /&gt;雖然好像看起來只是"填入"ㄧ些程式碼，但是這部分又與整個硬體運作以及BIOS Vendor所提供的程式碼的"穩定度"有很大的關係，所以如果只是單純修改這些程式碼約1年可以上手，但是如果要能處理bug，那麼可能就需要多年的經 驗累積了。因此在這種OEM/ODM BIOS與BIOS Vendor分工合作的情況之下，OEM/ODM端的BIOS有自己負責解決問題的地方，而BIOS Vendor也有自己負責要處理的地方，大家相互合作。&lt;br /&gt;&lt;br /&gt;說了這麼多，對於BIOS開發環境應該有所了解，但是最近案子開始在忙了，所以會寫Blog時間會比較少了，等過陣子等案子不忙的時候，我再告訴大家如何如果要實做一個類似BIOS vendor開發環境，你需要哪些工具，還有怎樣子做。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-2552065237935405545?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/2552065237935405545/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=2552065237935405545' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/2552065237935405545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/2552065237935405545'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/06/bios.html' title='BIOS開發'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-7690655037714616640</id><published>2008-06-27T20:46:00.000-07:00</published><updated>2008-06-27T21:19:00.468-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/Firmware'/><title type='text'>EFI(Extensible Firmware Interface)之2</title><content type='html'>Extensible Firmware Interface ，EFI 簡介   by Harrison&lt;br /&gt;(轉貼於"小華的部落格http://biosengineer.blogspot.com/")&lt;br /&gt;&lt;br /&gt;Extensible Firmware Interface (EFI) 是一個規範，他規範了一個介面，界於作業系統(例如: Windows)與平台韌體(Platform firmware)之間的一個橋樑。 EFI的改進被用來取代傳統BIOS的介面(這個傳統的介面被稱之為IBM PC compatible PC 的BIOS或稱之為Legacy BIOS).&lt;br /&gt;&lt;br /&gt;­最初EFI是由Intel 所主導發展，目前則由UEFI論壇(&lt;a title="Unified EFI Forum" href="http://en.wikipedia.org/wiki/Unified_EFI_Forum"&gt;Unified EFI Forum&lt;/a&gt;) 的會員一起共同維護，這便是眾所皆知的UEFI (Unified EFI，統一的EFI).&lt;br /&gt;&lt;br /&gt;&lt;a name="History"&gt;&lt;/a&gt;發展歷史 History&lt;br /&gt;最初EFI發展動機是為了在1990年中的Intel-HP Itanium 系統，當時的PC BIOS有一個限制(支援16 bit 的處理器模式，1MB 位址空間與AT 硬體架構)，而這個限制使的他無法支援大型伺服器平台的系統Intel-HP Itanium。 最初的時候Intel 只是為了解決這些BIOS啟動時的限制，後來就乾脆改變它的名稱，且稱之為EFI。&lt;br /&gt;&lt;br /&gt;EFI specification 1.02 在2000年12月的時候由Intel發行 (Version 1.01 則是Intel 最初發行的版本，但是它裡面有一些錯誤存在。)&lt;br /&gt;&lt;br /&gt;EFI specification 1.10 在2002年12月1日發行，他包含了 EFI driver model 增強版。&lt;br /&gt;到了 2005年， Intel 將這個版本貢獻給 &lt;a title="UEFI Forum" href="http://en.wikipedia.org/wiki/UEFI_Forum"&gt;UEFI Forum&lt;/a&gt;來幫助大家討論，藉以提升EFI開發環境以及提升他的功能。 所以將EFI改稱為 Unified EFI (UEFI)來代表這個改變。&lt;br /&gt;&lt;br /&gt;而UEFI Forum 目前2007年1月7日的最新版本是UEFI specification version 2.1 。它增加了&lt;a title="Cryptography" href="http://en.wikipedia.org/wiki/Cryptography"&gt;cryptography&lt;/a&gt;，network authentication， IPv6 support和&lt;a title="User Interface" href="http://en.wikipedia.org/wiki/User_Interface"&gt;User Interface&lt;/a&gt; 架構(簡稱 UEFI使用者介面，或稱HII)。&lt;br /&gt;&lt;a name="Contents"&gt;&lt;/a&gt;&lt;br /&gt;EFI specification 所定義的介面中包含platform information的Data tables還有啟動服務(Boot Services)與Runtime services (例如如何去啟動OS loader 或是啟動 ㄧ個EFI-aware OS)。&lt;br /&gt;&lt;br /&gt;另外像是原本就存在於PC BIOS中的其他類型的增強型BIOS(像是SMBIOS或是ACPI )也都可以存在於EFI之中，因為他們並沒有使用16-bit runtime interface去服務他們。&lt;a name="Services"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Services&lt;br /&gt;EFI 定義了啟動服務( boot services)，這些服務包含了文字與圖形支援，這些支援可以針對不同的設備(device)，匯流排(bus)，檔案服務(file services)，Block…等， 還有一些runtime services 就像是date， time 和 &lt;a title="NVRAM" href="http://en.wikipedia.org/wiki/NVRAM"&gt;NVRAM&lt;/a&gt; services.&lt;br /&gt;&lt;br /&gt;&lt;a name="Device_drivers"&gt;&lt;/a&gt;Device drivers&lt;br /&gt;EFI針對標準設備驅動程式的增加部份，它提供了處理器-非依賴的設備驅動程式環境(Processor-independent device driver environment) 稱之為EFI Byte Code 或 EBC。依照UEFI 規範中的系統需求中提到，系統需要裝設一個翻譯器(interpreter)來提供EBC Image 的裝載(resides in)或是載入(Loaded into)進去這個環境。&lt;br /&gt;&lt;br /&gt;因此，EBC會類似被模擬成Open Firmware的樣子。而這個Open Firmware(他是一個硬體-非依賴韌體，Hardware-independent firmware)是就像是使用在 &lt;a title="PowerPC" href="http://en.wikipedia.org/wiki/PowerPC"&gt;PowerPC&lt;/a&gt;-架構的 &lt;a title="Apple Macintosh" href="http://en.wikipedia.org/wiki/Apple_Macintosh"&gt;Apple Macintosh&lt;/a&gt; 電腦或是 &lt;a title="Sun Microsystems" href="http://en.wikipedia.org/wiki/Sun_Microsystems"&gt;Sun Microsystems&lt;/a&gt; &lt;a title="SPARC" href="http://en.wikipedia.org/wiki/SPARC"&gt;SPARC&lt;/a&gt; 電腦，或是其他也在使用Open Firmware的電腦。&lt;br /&gt;&lt;br /&gt;一些非EBC(non-EBC architecture EFI device drivers types)架構的EFI 設備驅動程式型態則有一個介面來支援OS對他們的使用。&lt;br /&gt;&lt;br /&gt;這些介面可以允許OS去依賴EFI所提供的一些基本設備驅動程式(像是圖形驅動程式，網路驅動程式的支援)來初始化一些設備，直到OS所需的驅動程式全被載入為止。&lt;br /&gt;&lt;br /&gt;&lt;a name="Boot_Manager"&gt;&lt;/a&gt;Boot Manager&lt;br /&gt;EFI boot manager 也被使用來選擇和載入一個作業系統(Operating system)，移除則需要決定一個Boot Loader的管理機制 (Boot Loader變成EFI 應用程式的類型)，在Framework架構中是屬於Boot Device Select，BDS階段。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="Disk_Support"&gt;&lt;/a&gt;Disk Support&lt;br /&gt;除了標準PC磁碟分割(Disk partition scheme)架構&lt;a title="Master boot record" href="http://en.wikipedia.org/wiki/Master_boot_record"&gt;Master boot record&lt;/a&gt; (MBR)之外, EFI 還增加了一個新的支援 &lt;a title="GUID Partition Table" href="http://en.wikipedia.org/wiki/GUID_Partition_Table"&gt;GUID Partition Table&lt;/a&gt; (GPT)， 而這個新的支援則不受到標準MBR的侷限。 在EFI specification 並沒有描述你要使用哪一種的&lt;a title="File system" href="http://en.wikipedia.org/wiki/File_system"&gt;file system&lt;/a&gt;; 而典型的EFI在實作上則內定支援使用 &lt;a title="FAT32" href="http://en.wikipedia.org/wiki/FAT32"&gt;FAT32&lt;/a&gt; 的檔案系統。&lt;br /&gt;&lt;br /&gt;&lt;a name="The_EFI_Shell"&gt;&lt;/a&gt;The EFI Shell&lt;br /&gt;EFI 社群(community)建立了一個開放式源碼(Open Source)與介殼程式環境(Shell environment)，是使用者與作業系統溝通的程式，負責解譯及執行使用者下達給作業系統的指令。&lt;br /&gt;&lt;br /&gt;­所以EFI Shell並不是直接的啟動進入到OS，因此在某些情況之下，使用者可以進入到EFI shell。而這個shell是一個EFI application，它可以直接存在於platform ROM(直接燒入在裡面)，或是在有驅動程式的ROM的設備上面(透過驅動程式來載入EFI Shell)。&lt;br /&gt;&lt;br /&gt;像在MacBook (Apple 的Intel CPU架構的筆記型電腦)，你可以把EFI shell 應用程式放在USB隨身碟，而在開機的時候按著"Option"，然後就會看到一個選擇開機項目的畫面，選擇你的USB隨身碟，那麼就可以看到一個長的很 像DOS的畫面，而這個畫面就是EFI Shell。&lt;br /&gt;&lt;br /&gt;而這個Shell可以被使用來執行一個EFI 的應用程式，像是 setup， OS install， diagnostic(診斷分析程式)或是Configuration utilities和System flash updates…等，他也能直接的播放CDs 或是DVDs ­而不需要進入到一個完整的OS環境底下，它提供了一個適當的環境來開發EFI應用程式。另外Shell commands也可能可以用來複製，搬移檔案或是目錄(如果你的Shell 有支援)，而設備驅動程式也可以利用他去載入或是卸載，而一個完整的TCP/IP 堆疊(TCP/IP 7層架構)也可以使用EFI Shell被完整的使用。&lt;br /&gt;&lt;br /&gt;簡單說就是EFI Shell提供了一個不需要進入OS環境也可以處理你需要的工作的一個環境。最後EFI shell支援腳本，而他的副檔名是 .nsh files，他就像是DOS下的批次檔( &lt;a title="Batch file" href="http://en.wikipedia.org/wiki/Batch_file"&gt;batch files&lt;/a&gt;)。&lt;br /&gt;Shell Command的指令名稱繼承了&lt;a title="COMMAND.COM" href="http://en.wikipedia.org/wiki/COMMAND.COM"&gt;DOS command interpreter&lt;/a&gt; 或是 &lt;a title="Unix shell" href="http://en.wikipedia.org/wiki/Unix_shell"&gt;Unix shell&lt;/a&gt;(操作起來像是混合體，有時出現DOS指令的名稱，有時是Unix的名稱) ，­而EFI Shell其實就是可以看作成在BIOS裡面的一個DOS環境。&lt;br /&gt;&lt;br /&gt;&lt;a name="Extensions"&gt;&lt;/a&gt;Extensions&lt;br /&gt;EFI延伸功能之中所描述，EFI可以從任何虛擬的非揮發性儲存設備載入並且連接到電腦之中，例如一個&lt;a title="Original equipment manufacturer" href="http://en.wikipedia.org/wiki/Original_equipment_manufacturer"&gt;original equipment manufacturer&lt;/a&gt; (OEM) 廠商在賣系統的時候將EFI 分割區放硬碟中，而要將這些功能載入的程式則放在主機板上的ROM之中，簡單說就是BIOS ROM裡面的程式可以去硬碟把EFI 功能載入出來執行，例如一些測試程式放在硬碟，然後EFI開機的時候去硬碟讀取這些程式出來執行。&lt;br /&gt;&lt;br /&gt;&lt;a name="Implementation_and_adoption"&gt;&lt;/a&gt;&lt;a name="Intel_Platform_Innovation_Framework_for_"&gt;&lt;/a&gt;Intel Platform Innovation Framework for EFI&lt;br /&gt;Intel 在其平台上為了EFI去建立了一個新框架(Framework)，而這個框架的最初代號叫做Tiano，這個框架非常的完整，它包含了EFI對原本傳統韌 體的所有支援，他也可以透過所謂的compatibility support module(CSM)來支援傳統的PC BIOS，簡單說就是傳統BIOS能做的EFI也能做，但是不是完整支援就要看CSM支援的程度。&lt;br /&gt;&lt;br /&gt;特別是，這個框架包含了在Power-On後，所有必要的初始化步驟去初始化一個平台(Platform);但是這些步驟的運作並沒有被定義在EFI specification內，而是被定義在 &lt;a title="Platform Initialization Specification" href="http://en.wikipedia.org/wiki/Platform_Initialization_Specification"&gt;Platform Initialization Specification&lt;/a&gt;內的某個章節。&lt;br /&gt;&lt;br /&gt;Intel 並沒有將這個架構完整的開放給一般的End-User知道，他只有開放這些資訊給一些獨立的BIOS 廠商(稱之為IBV)，像是安邁 (&lt;a title="American Megatrends" href="http://en.wikipedia.org/wiki/American_Megatrends"&gt;American Megatrends&lt;/a&gt; ，AMI) 或是系微(&lt;a title="Insyde Software" href="http://en.wikipedia.org/wiki/Insyde_Software"&gt;Insyde Software&lt;/a&gt;) …等的BIOS韌體供應商。&lt;br /&gt;&lt;br /&gt;而在&lt;a title="http://www.tianocore.org/" href="http://www.tianocore.org/"&gt;TianoCore project&lt;/a&gt;(也就是所謂的EFI Developer Kit ，EDK)的Open source之中，會提到如何去開發這個Framework。這個開發工具中含括了EFI的一些硬體初始化的程式碼(只針對一些硬體，但並不包含韌體本身) ，至於這些程式碼的授權包含&lt;a title="BSD license" href="http://en.wikipedia.org/wiki/BSD_license"&gt;BSD license&lt;/a&gt; 和 &lt;a title="Eclipse Public License" href="http://en.wikipedia.org/wiki/Eclipse_Public_License"&gt;Eclipse Public License&lt;/a&gt;…等。&lt;br /&gt;&lt;br /&gt;而Tiano是為了取代BIOS的一種框架，所以透過EFI可以讓PC的設備自己撰寫一個驅動程式來管理這個設備。而對於開放原始碼來說，這也代表大家可 以從TianoCore.org 下載這個專案，然後以BSD（Berkley Software Distribution）的授權方式來生產你的產品。BSD的授權，你自己去修改它的軟體並且發展出屬於你自己的產品，但BSD並不會去要求你把修改的 地方公開出來，而這種方法會有助於你去保護你的智慧財產權。&lt;br /&gt;&lt;br /&gt;Platforms that use EFI or the Framework&lt;br /&gt;最早使用EFI 的平台式 &lt;a title="Intel" href="http://en.wikipedia.org/wiki/Intel"&gt;Intel&lt;/a&gt;的第一個&lt;a title="Itanium" href="http://en.wikipedia.org/wiki/Itanium"&gt;Itanium&lt;/a&gt; 工作站和伺服器，他們支援EFI 1.02。 接著是&lt;a title="Hewlett-Packard" href="http://en.wikipedia.org/wiki/Hewlett-Packard"&gt;Hewlett-Packard&lt;/a&gt;的第一個 &lt;a title="Itanium 2" href="http://en.wikipedia.org/wiki/Itanium_2"&gt;Itanium 2&lt;/a&gt; 系統(2002年發表)，支援EFI 1.10; 而這些系統都可以啟動 &lt;a title="Windows" href="http://en.wikipedia.org/wiki/Windows"&gt;Windows&lt;/a&gt;, &lt;a title="Linux" href="http://en.wikipedia.org/wiki/Linux"&gt;Linux&lt;/a&gt;, &lt;a title="FreeBSD" href="http://en.wikipedia.org/wiki/FreeBSD"&gt;FreeBSD&lt;/a&gt; 和&lt;a title="HP-UX" href="http://en.wikipedia.org/wiki/HP-UX"&gt;HP-UX&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;不管是Itanium或是 Itanium 2 系統，他們在出貨的時候都是使用EFI compliant firmware，且須遵照DIG64 specifications。&lt;br /&gt;&lt;br /&gt;在&lt;a title="2003" href="http://en.wikipedia.org/wiki/2003"&gt;2003&lt;/a&gt;的11月, &lt;a title="Gateway, Inc." href="http://en.wikipedia.org/wiki/Gateway%2C_Inc."&gt;Gateway&lt;/a&gt; 介紹他們的Gateway 610 Media Center，第一個x86 Windows-based 的電腦系統使用了這個框架(Framework)，而韌體供應商則是 Insyde Software's InsydeH2O。而這個韌體依舊是依靠賴傳統BIOS相容介面的方式去實作出這個框架來啟動微軟系統，簡單說就是EFI 的框架去模擬成傳統BIOS，因為Windows並不認識EFI，所以利用EFI框架做出模組(Module)方式去符合目前x86 架構。&lt;br /&gt;&lt;br /&gt;在2006年1月，&lt;a title="Apple Computer" href="http://en.wikipedia.org/wiki/Apple_Computer"&gt;Apple Computer&lt;/a&gt; 販售了屬於他們第一次使用 &lt;a title="Intel" href="http://en.wikipedia.org/wiki/Intel"&gt;Intel&lt;/a&gt;-based的Macintosh電腦， 這個系統使用了EFI和新框架Framework來取代了原本他們在Power PC-Based 一直以來都在使用的 &lt;a title="Open Firmware" href="http://en.wikipedia.org/wiki/Open_Firmware"&gt;Open Firmware&lt;/a&gt;，而在 2006年4月5日， Apple 公佈了一個 &lt;a title="Boot Camp" href="http://en.wikipedia.org/wiki/Boot_Camp"&gt;Boot Camp&lt;/a&gt; 應用程式，這是一個非破壞性的分割工具(non-destructive partitioning tool)去幫助Apple的使用這去安裝Windows XP驅動程式甚至是系統到麥金塔的電腦之中。&lt;br /&gt;&lt;br /&gt;而同時，Apple的韌體的也做了更新支援，讓傳統的BIOS支援去它的EFI實作。在此之後，所有的麥金塔系統(Intel-Based)也都是使用使 這種韌體(Firmware)出貨。 現在所有目前的Macintosh systems 也都可以啟動傳統的作業系統Windows XP，簡單說就是WindowsXP不認識EFI，而Apple機器內如果裝了Windows XP就必須使用Legacy BIOS方式去啟動Windows XP，因此Apple更新了EFI的Firmware支援，去模擬出一個傳統的BIOS介面來支援，應該也是叫做CSM。&lt;br /&gt;&lt;br /&gt;從2005年之後，幾乎大多數的Intel 主機板都開始出貨這種支援新的框架架構的主機板的韌體(Framework-based firmware)。現在像是一些新的mobile,，desktop和 server 產品，在2006年起，也都開始使用這種框架。&lt;br /&gt;&lt;br /&gt;自2005起，EFI也開始被實作在非PC架構的系統上，像是嵌入式系統，像是 &lt;a title="Embedded system" href="http://en.wikipedia.org/wiki/Embedded_system"&gt;embedded systems&lt;/a&gt; based 的 &lt;a title="XScale" href="http://en.wikipedia.org/wiki/XScale"&gt;XScale&lt;/a&gt; cores。&lt;br /&gt;&lt;br /&gt;而EDK 還包含了NT32 的目標(Target)，也就是說它允許EFI Frimware和EFI Application 去執行一個&lt;a title="Microsoft Windows" href="http://en.wikipedia.org/wiki/Microsoft_Windows"&gt;Windows&lt;/a&gt; 應用程式。&lt;br /&gt;&lt;br /&gt;&lt;a name="Operating_Systems"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a name="Security_and_freedom_concerns"&gt;&lt;/a&gt;Security and freedom concerns&lt;br /&gt;According to Ron Minnich, the lead developer for &lt;a title="LinuxBIOS" href="http://en.wikipedia.org/wiki/LinuxBIOS"&gt;LinuxBIOS&lt;/a&gt;, one of the stated goals of EFI is to protect hardware vendors "intellectual property"&lt;a title="" href="http://en.wikipedia.org/wiki/Extensible_Firmware_Interface#_note-minnich#_note-minnich"&gt;[15]&lt;/a&gt;. This raises security concerns and notably makes creating a &lt;a title="Free software" href="http://en.wikipedia.org/wiki/Free_software"&gt;free software&lt;/a&gt; BIOS impossible.&lt;br /&gt;EFI could be used to create a "DRM BIOS", thus letting vendors build computers which limit what the user can do.&lt;br /&gt;&lt;br /&gt;有關於自由軟體運動v.s EFI 請參考下列網站說明：&lt;br /&gt;&lt;a href="http://taiwan.cnet.com/enterprise/technology/0,2000062852,20098242,00.htm"&gt;http://taiwan.cnet.com/enterprise/technology/0,2000062852,20098242,00.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;維基百科&lt;br /&gt;CNET&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-7690655037714616640?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/7690655037714616640/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=7690655037714616640' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/7690655037714616640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/7690655037714616640'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/06/efiextensible-firmware-interface2.html' title='EFI(Extensible Firmware Interface)之2'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-6904102882301296232</id><published>2008-06-27T20:31:00.000-07:00</published><updated>2008-06-27T20:46:12.823-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/Firmware'/><title type='text'>EFI(Extensible Firmware Interface)之1</title><content type='html'>EFI為Extensible Firmware Interface的簡稱。&lt;br /&gt; 中文叫做可延伸式韌體界面...&lt;br /&gt; 這裡有詳細的討論文章可以參考&lt;br /&gt; http://taiwan.cnet.com/enterprise/technology/0,2000062852,20098242,00.htm&lt;br /&gt;&lt;br /&gt;Intel 搞的EFI叫Tiano，EFI只是一個SPEC名稱，&lt;br /&gt;Tiano才是Intel搞出來bios source code的名稱。&lt;br /&gt;EFI就是要各硬體廠商自己寫BIOS，就是所謂的&lt;br /&gt;EFI driver，然後BIOS vendor只要整合combine&lt;br /&gt;，甚至end user可以不改source code自己load driver&lt;br /&gt;unload driver，很方便，可是對傳統的bios vendor就不妙了，&lt;br /&gt;他們的角色變的可有可無啦。&lt;br /&gt;&lt;br /&gt;现在TIANO已经Open Source了.&lt;br /&gt;你可以在&lt;br /&gt;http:\\www.tianocore.org&lt;br /&gt;上获得它的source code.&lt;br /&gt;&lt;br /&gt;最近又出現一種新發展標準, 叫uEFI (Unified Extensible Firmware Interface), :002: 據了解...它是建構在EFI 1.10 規格所發展出來的新標準。&lt;br /&gt; 目前力拱uEFI的大廠, 包括&lt;br /&gt;Phoenix Technologies (http://www.phoenix.com/en/Home/default.htm)&lt;br /&gt; Intel (http://www.intel.com/)&lt;br /&gt; Microsoft (http://www.microsoft.com/)&lt;br /&gt; AMD (http://www.amd.com/us-en/)&lt;br /&gt; American Megatrends Inc. (http://www.ami.com/)&lt;br /&gt; Dell (http://www.dell.com/)&lt;br /&gt; Hewlett Packard (http://www.hp.com/)&lt;br /&gt; IBM (http://www.ibm.com/us/)&lt;br /&gt; Insyde (http://www.insydesw.com.tw/en/index.asp)&lt;br /&gt;看來它將會取代EFI, 成為業界發展的主流啦:&lt;br /&gt;&lt;br /&gt;詳細內容可以至http://www.uefi.org/index.php?pg=2獲得!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-6904102882301296232?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/6904102882301296232/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=6904102882301296232' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/6904102882301296232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/6904102882301296232'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/06/efiextensible-firmware-interface1.html' title='EFI(Extensible Firmware Interface)之1'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-3871224526468965929</id><published>2008-05-09T08:21:00.000-07:00</published><updated>2008-05-09T08:27:46.806-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/計算機/Playstation2'/><title type='text'>Sound and Vision: A Technical Overview of the Emotion Engine</title><content type='html'>&lt;span style="font-family: courier new;"&gt;    By &lt;/span&gt;&lt;a style="font-family: courier new;" href="http://arstechnica.com/authors.ars/hannibal"&gt;Jon Stokes&lt;/a&gt;&lt;span style="font-family: courier new;"&gt; |     Published: February 16, 2000 - 07:00AM CT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2 style="font-family: courier new;"&gt;Preface&lt;/h2&gt;      &lt;div style="font-family: courier new;" class="Body"&gt;      &lt;p&gt;I'll spare you the obligatory opening fluff paragraph that goes something like "when Sony first announced the Emotion Engine...," and I'll cut right to the chase.  The Emotion Engine is &lt;i&gt;weird&lt;/i&gt;.  It's so weird, in fact, that it took me quite a while to figure out how it works, and as a result, it's going to take me quite a while to explain it. The result of this is that I want to approach this topic in two parts. &lt;/p&gt;  &lt;p&gt;The first part of this article will not be as technically granular as most of my previous work because I want to provide a pertinent overview and a context for understanding the Emotion Engine in detail, without addressing some of the more complex architectural issues. For the technically uninitiated, the first part will suffice in bringing you the mojo you need (and hopefully wetting your whistle for more). With the foundation laid in part I, the second part of this article will, then, delve into the depths of the Emotion Engine. This second part is probably less accessible than the first, because to understand it, you'll need to be familiar with CPU architectural concepts like pipelining, VLIW, SIMD, instruction latency, throughput, etc. If you are not familiar with these terms, I'd suggest checking out some of &lt;a href="http://www.arstechnica.com/cpu/index.html"&gt;my previous work&lt;/a&gt;. [&lt;b&gt;Update 10/05/00&lt;/b&gt;: I've since written a &lt;a href="http://www.arstechnica.com/cpu/2q00/ps2/ps2vspc-1.html"&gt;system-level comparison of the PS2 and the PC&lt;/a&gt;, which should be a bit more accessible than this article. I'd suggest reading it first.]&lt;/p&gt; &lt;p&gt;Also, a disclaimer before I get started. The literature on the PS2 offers conflicting numbers for the sizes of the various caches in the Emotion Engine. These numbers are usually the last to be fixed at production time, and I'm not sure of the latest ones. However, I used the numbers that I thought were most recent. Feel free to correct me if you know otherwise.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;h3&gt;Part I: General Playstation 2 Overview&lt;/h3&gt; &lt;p&gt;The bulk of this article will deal exclusively with design and function of the heart of Sony's &lt;a href="http://www.arstechnica.com/cpu/1q99/playstation2-pr.html"&gt;Playstation 2&lt;/a&gt;: the Emotion Engine. However, because of the way Sony designed the PS2, it's not really possible to look only at the Emotion Engine, and ignore the rest of the system. So we'll start out by looking at the system as a whole, and then we'll narrow the discussion to the Emotion Engine. &lt;/p&gt;  &lt;p&gt;We have to look at the Emotion Engine in the context of the overall design of the PS2 because, unlike a modern PC's CPU, the Emotion Engine is not really a general purpose computing device. The CPU of a PC is designed from the ground up to run SPEC benchmarks...er, application code as fast as possible. Since application code comes in a wide variety of forms and performs a wide variety of functions, CPU hardware must be general enough to give acceptable performance on almost anything a coder throws at it. In a PC system, this general-purpose CPU is augmented by special purpose hardware for things like video acceleration, network communications, sound processing, etc..&lt;/p&gt; &lt;p&gt;The PS2 is in a slightly different situation. The PS2's designers had the luxury of designing hardware whose main purpose is to run one type of application extremely well: the 3D game. Sure, the PS2 can run web browsers, mail clients, and other types of software, but that's all secondary. The main thing the PS2 does is 3D gaming, which means generating the kind of immersive sound and vision that places you in a virtual world. Nearly all of the PS2's hardware is dedicated to providing some specific portion of that audiovisual gaming experience. &lt;/p&gt; &lt;p&gt;So just how does the PS2 generate 3D graphics and sound? Let's take a look at the main parts of the PS2.&lt;/p&gt; &lt;div align="center"&gt;   &lt;img src="http://www.arstechnica.com/reviews/1q00/playstation2/figure1.gif" border="0" height="433" width="562" /&gt;&lt;/div&gt; &lt;div align="center"&gt;  &lt;/div&gt; &lt;p&gt;In the above picture, you can see that there are four main parts to the device. Let's look at the one at a time.  The &lt;a href="http://www.arstechnica.com/cpu/1q99/playstation2-io.html"&gt;I/O Processor&lt;/a&gt; (IOP) handles all USB, FireWire, and game controller traffic. When you're playing a game on the PS2, the IOP takes your controller input and sends it to the &lt;a href="http://www.arstechnica.com/cpu/1q99/playstation2-cpu.html"&gt;Emotion Engine&lt;/a&gt; so that the Emotion Engine can update the state of the game world appropriately. The Emotion Engine is the heart of the PS2, and the part that really makes it unique.  The Emotion Engine handles two primary types of calculations and one secondary type:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;b&gt;Geometry calculations&lt;/b&gt;: transforms, translations, etc. &lt;/li&gt;&lt;li&gt;&lt;b&gt;Behavior/World simulation&lt;/b&gt;: enemy AI, calculating the friction between two objects, calculating the height of a wave on a pond, etc. &lt;/li&gt;&lt;li&gt;&lt;b&gt;Misc. functions&lt;/b&gt;: program control, housekeeping, etc.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;When all is said and done, the Emotion Engine's job is to produce &lt;b&gt;display lists&lt;/b&gt; (sequences of rendering commands) to send to the &lt;a href="http://www.arstechnica.com/cpu/1q99/playstation2-gfx.html"&gt;Graphics Synthesizer&lt;/a&gt;.  The Graphics Synth is sort of a souped-up video accelerator. It does all the standard video acceleration functions, and its job is to render the display lists that the EE sends it.  Finally, the Sound Processor is the "soundcard" of the PS2. It lets you do 3D digital sound using AC-3 and DTS.&lt;/p&gt;  &lt;p&gt;The Emotion Engine is sort of a combination CPU and DSP Processor, whose main function is simulating 3D worlds. So before we discuss the Emotion Engine's architecture in detail, we should talk a bit about DSP (Digital Signal Processing) and 3D graphics.&lt;/p&gt;       &lt;/div&gt;&lt;br /&gt;&lt;h2 style="font-family: courier new;"&gt;3D rendering and DSP basics&lt;/h2&gt;      &lt;div style="font-family: courier new;" class="Body"&gt;      &lt;h3&gt;Background: 3D rendering and DSP basics&lt;/h3&gt; &lt;p&gt;A DSP processor, in a nutshell, takes in massive amounts of input data and performs repetitive, loop-based calculations on it to produce massive amounts of output data. Speed and bandwidth are of the essence in digital signal processing. One of the most useful and important features that modern DSPs have is the ability to do a &lt;b&gt;MAC&lt;/b&gt; (multiply-accumulate) in a single cycle. A MAC is used in a variety of vector calculations, the most common of these being the &lt;b&gt;dot product&lt;/b&gt;. The dot product involves summing the products of vector element pairs, and it requires a series of MACs to calculate. The Emotion Engine has a total of &lt;b&gt;10 FMACs&lt;/b&gt; (Floating-Point Multiply-Accumulators), each of which can do one 32-bit floating-point MAC operation per cycle. If you were wondering what's behind those outrageous polygon counts that Sony publishes for the PS2, now you know; the PS2 can do a lots of MACs, very, very quickly.&lt;/p&gt; &lt;p&gt;The second big requirement for a DSP processor is memory bandwidth and availability. The PS2 is full of small, strategically placed caches (the SPRAM, VU instruction and data memory, etc.) that can be accessed in a single cycle. More importantly, the &lt;b&gt;SPRAM&lt;/b&gt; (Scratch Pad RAM--more on this in a moment) interleaves those single-cycle CPU accesses with slower memory bus DMA accesses, so the SPRAM doesn't get tied up by the slower main bus. Finally, the Emotion Engine contains a &lt;b&gt;10-channel DMA controller (DMAC)&lt;/b&gt; to manage up to 10 simultaneous transfers on the Emotion Engine's internal 128-bit, 64-bit, and 16-bit buses. With the DMA controller directing all that bus traffic between the various components and types of memory, the other components are free to do their thang without having to manage data transfers themselves. &lt;/p&gt;  &lt;p&gt;The final bit of background info that's pertinent to our project involves 3D rendering. This isn't the place to discuss 3D rendering basics or anything like that (and I'm not really the guy to discuss them either), but there is one aspect of the rendering process we should cover. The Graphics Synthesizer on the PS2 takes data from the Emotion Engine in a very specific form: the &lt;b&gt;display list&lt;/b&gt;. The display list is a sequence of drawing commands that tells the GS which primitive shapes to draw and where. A typical display list contains commands to draw vertices, shade the faces of polygons, render bitmaps, etc.--basically, the commands required to actually draw the virtual, 3D world of the game. The Graphics Interface unit (GIF) can take multiple display lists from multiple units inside the Emotion Engine and combine them to allow the Graphics Synth to produce composite images. Or, it can arbitrate between the lists to decide which ones get drawn and when. &lt;/p&gt; &lt;p&gt;Since the Graphics Synthesizer eats display lists, the Emotion Engine's main job is to feed those lists to it. The Emotion Engine's various subunits can operate independently of each other in order to asynchronously generate multiple display lists to send to the GS. Since the Graphics Synth's interface unit, the GIF, handles,  tracks and manages all of these display lists, Emotion Engine doesn't really have to waste computational resources or internal bus bandwidth keeping track of them. Its various sub-units just concentrate on cranking them out and sending them over a dedicated, 64-bit bus to the GIF. Render 'em all, and let the GIF sort 'em out.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;The Emotion Engine: Basic Architecture&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;As was stated above, the Emotion Engine's primary piece of output is the display list. Generating those display lists involves a number of steps besides just the obvious geometry calculations. For instance, if the software you're running is a racing game, then you've got to first calculate the virtual friction between a car's tires and the road (among other things) when the car turns a corner before you can draw the next scene. Or if the game is an FPS, you have to run the enemy AI's path-finding code so you'll know where to place them on each frame. So there's a lot of stuff that goes on behind the scenes and affects the output on the screen. All of this labor--geometry calculations, physics calculations, AI, data transfers, etc.-- is divided up among the following units:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;&lt;b&gt;MIPS III CPU core&lt;/b&gt;   &lt;/li&gt;&lt;li&gt;&lt;b&gt;Vector Unit&lt;/b&gt; (which is actually two vector units, VU0 and VU1).   &lt;/li&gt;&lt;li&gt;floating-point coprocessor, or FPU   &lt;/li&gt;&lt;li&gt;&lt;b&gt;Image Processing Unit&lt;/b&gt; (The IPU is basically an MPEG2 decoder with     some other capabilities).   &lt;/li&gt;&lt;li&gt;&lt;b&gt;10-channel DMA controller&lt;/b&gt;     &lt;/li&gt;&lt;li&gt;&lt;b&gt;Graphics Interface unit&lt;/b&gt;. (GIF)   &lt;/li&gt;&lt;li&gt;&lt;b&gt;RDRAM interface&lt;/b&gt; and &lt;b&gt;I/O interface&lt;/b&gt; (for connecting to the two     RDRAM banks and the I/O Processor, respectively))&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;All of the above components are integrated onto one die and are connected (with the exception of the FPU) via a shared 128-bit internal bus. &lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://www.arstechnica.com/reviews/1q00/playstation2/figure2.gif" border="0" height="377" width="545" /&gt;&lt;/div&gt; &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;As was noted in the bullet list, the VU can be further divided into two independent, &lt;b&gt;128-bit SIMD/VLIW&lt;/b&gt; vector processing units, &lt;b&gt;VU0&lt;/b&gt; and &lt;b&gt;VU1&lt;/b&gt;.   These units, though they're microarchitecturally identical, are each intended to fill a specific role. Toshiba, who designed the Emotion Engine and licensed it to Sony, didn't feel that it was optimal to have three pieces of general purpose hardware (a CPU and two vector processors) that could be assigned to any task that was needed. Instead, they fixed the roles of the devices in advance, customized the devices to fit those roles, and organized them into logical units. In that respect, they're sort of like employees who've been grouped together on the basis of talent and assigned to teams. Let's look at the division of labor amongst the components:&lt;/p&gt; &lt;ol style="font-size: 10pt;"&gt;&lt;li&gt;&lt;b&gt;CPU + FPU&lt;/b&gt;: basic program control, housekeeping, etc.   &lt;/li&gt;&lt;li&gt;&lt;b&gt;CPU + FPU + VU0&lt;/b&gt;: behavior and emotion synthesis, physics     calculations, etc.   &lt;/li&gt;&lt;li&gt;&lt;b&gt;VU1&lt;/b&gt;: simple geometry calculations that produce display lists which     are sent directly to the Graphics Synth (via the GIF).   &lt;/li&gt;&lt;li&gt;&lt;b&gt;IPU&lt;/b&gt;: image decompression.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Of the above "teams," 2 and 3 are the ones I want to talk about here. &lt;/p&gt;  &lt;h3&gt;&lt;i&gt;The CPU/FPU/VU0 team&lt;/i&gt;&lt;/h3&gt; &lt;p&gt;The FPU and VU0 are &lt;b&gt;coprocessors&lt;/b&gt; for the MIPS III CPU core. This means that the CPU, the FPU, and VU0 all form a logical and functional unit (or a team, if you will) where the CPU is the primary, controlling device and the other two components extend its functionality. This CPU/FPU/VU0 team has a common set of goals: emotion synthesis, physics, behavior simulation, etc. I'll be going into much more detail on this collaboration in the second half of the article.&lt;/p&gt; &lt;p&gt;There are two main things that bind this team together and allow them to work very closely with each other. The first is the way they communicate with each other: VU0 and the FPU each have a dedicated, &lt;b&gt;128-bit coprocessor bus&lt;/b&gt; that connects them directly to the CPU. That way, they don't have to talk over the main, shared bus. The dedicated 128b bus also gives the CPU direct access to VU0's registers, and allows VU0 to fill its role as a standard, &lt;b&gt;MIPS III coprocessor&lt;/b&gt;.&lt;/p&gt; &lt;p&gt;The other important component that ties the CPU core and VU0 closely together is the &lt;b&gt;Scratch Pad RAM&lt;/b&gt;. The SPRAM is 16K of very fast RAM that lives on the CPU, but that both the CPU and VU0 can use to store data structures. The SPRAM also acts as a staging area for data, before it's sent out over the 128b internal bus. So the SPRAM is kind of like a shared workspace, where the CPU and VU0 collaborate on a piece of data before sending it out to wherever it needs to go next.&lt;/p&gt;  &lt;h3&gt;&lt;i&gt;The VU1/Graphics Synth team&lt;/i&gt;&lt;/h3&gt; &lt;p&gt;The other main team is composed of VU1 and the Graphics Synthesizer (which communicate via the GIF). Just as VU0 has a dedicated bus to the CPU core, VU1 has its own 128-bit dedicated path to the GIF. However, VU1 and the Graphics Synth aren't as closely tied together as are the CPU/FPU/VU0 group. VU1 and the GS are more like equal partners, and one doesn't control the other. You're probably wondering at this point just who does control VU1. This is an interesting question, and we'll discuss the answer when we talk about VU1's architecture in detail.&lt;/p&gt; &lt;h3&gt;&lt;i&gt;Putting the teams together&lt;/i&gt;&lt;/h3&gt; &lt;p&gt;Though the roles of the components were fixed by the PS2's designers, the overall design is still quite flexible. You divvy up an application's work amongst the teams however you like. For instance, the CPU/FPU/VU0 group can generate display lists and do geometry processing in parallel with VU1, so both groups can send display lists to the GIF at the same time. &lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://www.arstechnica.com/reviews/1q00/playstation2/figure3.gif" border="0" height="219" width="333" /&gt;&lt;/div&gt; &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;Or, the CPU/FPU/VU0 group can act as a sort of preprocessor for VU1. The CPU and co. process conditional branches in the rendering code and load data from main memory. They then generate world information that VU1 takes as input and and turns into a display list.&lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://www.arstechnica.com/reviews/1q00/playstation2/figure4.gif" border="0" height="219" width="333" /&gt;&lt;/div&gt; &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;This flexibility allows a developer to customize the process of generating and rendering the 3D environment to suit the needs of the specific application you're working with. &lt;/p&gt; &lt;p&gt;Now that we've gone over the basics of the Emotion Engine's operation, it's time to get hardcore. For the remainder of this article, I'll go in-depth on the MIPS III CPU core, VU0, and VU1. I'll give you the straight scoop on how these components are designed, and how they're integrated with each other. If terms like instruction latency, pipelining, and SIMD make your eyes glaze over, then you might want to check out here. If, however, you're an architecture enthusiast who eats CPU internals for breakfast, then hang on, because what follows is quite fascinating.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;The MIPS III CPU Core&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;The MIPS ISA has been a popular one for everything from game consoles to SGI workstations. Check out &lt;a href="http://www.mips.com/coolApps/s3p3.html"&gt;this page&lt;/a&gt; for the rundown on the various products that MIPS has shown up in. Among them are:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;Sony Playstation   &lt;/li&gt;&lt;li&gt;Nintendo 64   &lt;/li&gt;&lt;li&gt;Sony's WebTV   &lt;/li&gt;&lt;li&gt;Cassio's Cassiopeia PDA line.   &lt;/li&gt;&lt;li&gt;Sony's AIBO   &lt;/li&gt;&lt;li&gt;Various printers, copiers, scanners, etc.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In short, the MIPS ISA is an industry standard RISC ISA that's found in applications almost everywhere. Sony's MIPS III implementation is a &lt;b&gt;2-issue&lt;/b&gt; design that supports multimedia instruction set enhancements. It has 32, 128-bit GPRs (general purpose registers), and the following logical pipes:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;Two 64-bit integer ALUs   &lt;/li&gt;&lt;li&gt;a 128-big Load/Store Unit   &lt;/li&gt;&lt;li&gt;a Branch Execution Unit   &lt;/li&gt;&lt;li&gt;FPU Coprocessor (COP1)   &lt;/li&gt;&lt;li&gt;Vector Coprocessor, VU0 (COP2)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;(Here's a shot of the processor &lt;a href="http://www.arstechnica.com/reviews/1q00/playstation2/diagram1.html"&gt;block diagram&lt;/a&gt;.) The core can issue two 64-bit integer ops, or one integer op and one 128-bit Load/Store per cycle. For the obsessed, below is a handy chart that gives you a breakdown of all the types of instructions that can be issued concurrently:&lt;/p&gt;  &lt;table border="1" bordercolor="#006600" width="100%"&gt;   &lt;tbody&gt;     &lt;tr&gt;       &lt;td width="14%"&gt; &lt;/td&gt;       &lt;td align="center" width="14%"&gt;ALU&lt;/td&gt;       &lt;td align="center" width="14%"&gt;MAC0&lt;/td&gt;       &lt;td align="center" width="14%"&gt;MMI&lt;/td&gt;       &lt;td align="center" width="14%"&gt;Branch&lt;/td&gt;        &lt;td align="center" width="15%"&gt;COP1 oper.&lt;/td&gt;       &lt;td align="center" width="15%"&gt;COP2 oper.&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;ALU&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;MAC1&lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;      &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;LZC&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;Ld/St&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;SYNC&lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;      &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;Branch&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" bgcolor="#006600" width="14%"&gt; &lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;ERET&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" bgcolor="#006600" width="14%"&gt; &lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;COP0&lt;br /&gt;         ld/mov&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;COP1&lt;br /&gt;        ld/mov&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="14%"&gt;COP2&lt;br /&gt;         ld/mov&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;       &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;        &lt;td align="center" width="14%"&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;The two, fully-pipelined 64b integer ALU's are interesting, because they can either be used independently of each other (like in a normal CPU), or they can be locked together to do &lt;b&gt;128-bit integer SIMD&lt;/b&gt; in the following configurations: sixteen, 8-bit ops/cycle; eight, 16-bit ops/cycle; four, 32-bit ops/cycle. Pretty sweet. &lt;/p&gt; &lt;p&gt;To take advantage of the integer and FP SIMD capabilities that COP2 (COP2 = VU0) and the iALUs provide, Toshiba used extensions to the MIPS III ISA that include a comprehensive set of 128-bit SIMD instructions. Here are the instruction types that the CPU core supports:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;MUL/DIV instructions   &lt;/li&gt;&lt;li&gt;3-op MUL/MADD instructions   &lt;/li&gt;&lt;li&gt;Arithmetic ADD/SUB instructions   &lt;/li&gt;&lt;li&gt;Pack and extend instructions   &lt;/li&gt;&lt;li&gt;Min/Max instructions   &lt;/li&gt;&lt;li&gt;Absolute instructions   &lt;/li&gt;&lt;li&gt;Shift instructions   &lt;/li&gt;&lt;li&gt;Logical instructions   &lt;/li&gt;&lt;li&gt;Compare instructions   &lt;/li&gt;&lt;li&gt;Quadword Load/Store   &lt;/li&gt;&lt;li&gt;Miscellaneous instructions&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The CPU has a 16K instruction cache and an 8K data cache, each of which are two-way set associative. It's also capable of speculative execution using a simple, two-part branch prediction mechanism (a 64-entry BTAC and a BHT). Toshiba didn't waste a lot of resources on branch prediction, because the CPU's pipeline is a short 6 stages. Unlike with Willamette's extremely deep 20-stage pipeline, the penalty for a mispredict isn't too high. Here are the pipe stages:&lt;/p&gt; &lt;p&gt;1. PC select&lt;br /&gt; 2. Instruction fetch&lt;br /&gt;3. Instruction decode and register read&lt;br /&gt;4. Execute&lt;br /&gt;5. Cache access&lt;br /&gt;6. Writeback&lt;/p&gt; &lt;p&gt;Pretty standard RISC stuff. As usual, the execute stage can take a couple of cycles depending on the latencies of the instructions. &lt;/p&gt; &lt;p&gt;I discussed the SPRAM earlier, but I didn't mention that it has it's own address space that's accessible to the CPU via standard MIPS III Load/Store instructions. These loads and stores are interleaved with the main bus accesses to keep throughput up.&lt;/p&gt; &lt;p&gt;The FPU coprocessor, COP1, doesn't really deserve its own section. It's pretty much a straight-up, floating-point coprocessor that's a throwback to the classic RISC days when the FPU was a separate unit from the core. It executes basic, 32-bit MIPS coprocessor instructions using one FMAC unit and one FDIV unit, each of which is the same as the FMACs and FDIVs in the vector units. I'll talk about what these units do when we get to the vector unit discussion.&lt;/p&gt; &lt;p&gt;As you can tell from the above, the CPU core isn't really all that exciting. The only really cool things in it are the SPRAM and the 128-bit integer SIMD capabilities. Other than that, there's not much out of the ordinary going on. This unit is mostly here to handle program control flow by processing branch commands. It also does other stuff, but it doesn't do any of the &lt;i&gt;real heavy lifting&lt;/i&gt;--that's reserved for the vector units.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Vectors&lt;/h2&gt;            &lt;p&gt;Both VU0 and VU1 are &lt;i&gt;microarchitecturally identical&lt;/i&gt;, but they're not &lt;i&gt;functionally identical&lt;/i&gt;. VU1 has some extra features tacked onto the outside of it that help it do geometry processing, and VU0 has some features that it doesn't normally use (but that VU1 does). Toshiba did things this way to make the units easier to manufacture. Since VU0 is simpler, we'll start with it first.  Just keep in mind that a lot of what's said about VU0 also applies to VU1.&lt;/p&gt; &lt;h3&gt;&lt;i&gt;Vector Unit 0&lt;/i&gt;&lt;/h3&gt; &lt;p&gt;VU0 is a 128-bit &lt;b&gt;SIMD/VLIW design&lt;/b&gt;. (If you're confused about the term "SIMD/VLIW," don't worry, so was I at first. We'll discuss what this term means in a special section to follow.) Since VU0 is a coprocessor for the MIPS III core, it spends most of its time operating in &lt;b&gt;Coprocessor Mode&lt;/b&gt;. This means it looks like just another logical pipe (along with the integer ALUs) to the programmer. The instructions that make VU0 go are just 32-bit MIPS COP instructions, mixed in with integer, FPU, and branch instructions.  In this respect, VU0 looks a lot like the G4's Altivec unit. Often, in the rendering process, the CPU maintains a separate thread that controls VU0. The CPU places FP data on the dedicated bus in 128b chunks (w,x,y,z), which the VIF unpacks into 4 x 32 words for processing by the FMACs.&lt;/p&gt;  &lt;div align="center"&gt;&lt;img src="http://www.arstechnica.com/reviews/1q00/playstation2/figure5.gif" border="0" height="314" width="466" /&gt;&lt;/div&gt; &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;VU0 has its own set of 32, 128-bit FPRs (floating-point registers), each of which can hold 4, 32-bit single precision floating-point numbers. It also has 16, 16-bit integer registers for integer computation.&lt;/p&gt; &lt;p&gt;Here are the computational units available to VU0 (and VU1):&lt;/p&gt; &lt;ul&gt;&lt;li&gt;4 FMACs   &lt;/li&gt;&lt;li&gt;1 FDIV   &lt;/li&gt;&lt;li&gt;1 LSU   &lt;/li&gt;&lt;li&gt;1 ALU   &lt;/li&gt;&lt;li&gt;1 random number generator. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The first 5 units here, the 4 FMACs and the 1 FDIV, are sort of the heart of both VU0  and VU1 (which are themselves the heart of the Emotion Engine, which is itself the heart of the PS2). So this is where the magic happens. Each of the FMACs can do the following instructions:&lt;/p&gt;  &lt;div align="center"&gt;   &lt;center&gt;   &lt;table border="1" bordercolor="#008000"&gt;     &lt;tbody&gt;       &lt;tr&gt;         &lt;td width="81%"&gt;Floating-Point Multiply-Accumulate&lt;/td&gt;         &lt;td width="19%"&gt;1 cycle&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td width="81%"&gt;Min/Max&lt;/td&gt;         &lt;td width="19%"&gt;1 cycle&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;   &lt;/table&gt;   &lt;/center&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt; &lt;p&gt;The FDIV unit does the following instructions:&lt;/p&gt; &lt;div align="center"&gt;   &lt;center&gt;   &lt;table border="1" bordercolor="#008000"&gt;     &lt;tbody&gt;       &lt;tr&gt;         &lt;td width="81%"&gt;Floating-point Divide&lt;/td&gt;         &lt;td width="19%"&gt;7 cycles&lt;/td&gt;        &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="81%"&gt;Square Root&lt;/td&gt;         &lt;td width="19%"&gt;7 cycles&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="81%"&gt;Inverse Square Root&lt;/td&gt;          &lt;td width="19%"&gt;13 cycles&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;   &lt;/table&gt;   &lt;/center&gt; &lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;The bulk of the processing that the PS2 does to make a 3D game involves performing the above operations on lots and lots of data.&lt;/p&gt; &lt;p&gt;Now, those last three units in my list (LSU, ALU, and RNG) aren't normally shown in most charts as being part of VU0. I suspect this is because they aren't used in coprocessor mode. When VU0 is acting like a MIPS Coprocessor, it only uses the 4 FMACs. "Wait a minute," you're saying, "isn't VU0 always a MIPS coprocessor--you know, the 128-bit dedicated bus and stuff? You went to great lengths to make that point in the first half of the article."  Yeah, I did kind of insist that VU0 is on the CPU's "team," and that they share the same goals, and that it's bound to the CPU, etc.. This &lt;i&gt;is&lt;/i&gt; kind of misleading (although I would argue heuristically justifiable), but all will become clear in the final section. For now, just understand that VU0 mostly operates as a MIPS Coprocessor that handles any FP SIMD instructions that show up in the CPU's instruction stream. &lt;/p&gt; &lt;h3&gt;&lt;i&gt;Vector Unit 1&lt;/i&gt;&lt;/h3&gt; &lt;p&gt;VU1 is a fully independent SIMD/VLIW processor that includes all the architectural features of VU0, plus some additional mojo. These additions relate directly to VU1's role as a geometry processor for the Graphics Synth, and they help bind it more tightly to the GS. The primary addition is an extra functional unit, the Elemntary Functional Unit (EFU). The EFU is just 1 FMAC and 1 FDIV, just like the CPU's FPU. The EFU performs some of the more basic calculations required for geometry calculation.&lt;/p&gt; &lt;p&gt;Another big difference between VU1 and VU0 is that VU1 has 16K of data memory and 16K of instruction memory (as opposed to VU0's 8K data/8K instruction sizes). This larger amount of data memory is needed because VU1's role as a geometry processor requires that it handle much more data than VU0. &lt;/p&gt; &lt;p&gt;Finally, VU1 has multiple paths it can take to get data to the GIF (and on to the GS). Like VU0, VU1 can send display lists to the GIF via the main, 128b bus. Or, VU1's VIF can send data directly to the GIF. Finally, there's a direct connection between VU1's 16K data memory and the GIF, meaning that VU1 can work on a display list in data memory, and the DMAC can transfer the results directly to the GIF.&lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://www.arstechnica.com/reviews/1q00/playstation2/figure6.gif" border="0" height="352" width="543" /&gt;&lt;/div&gt;  &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;I have to pause here and note that there's some serious confusion in Sony's literature on the direct path between VU1 and the GIF. One diagram for a slide show seems to show the path as connecting the instruction memory to the GIF, another diagram quite obviously shows the path going from the lower execution unit to the GIF, and yet another shows it with the path connecting the data memory to the GIF. This last one is the only one that makes sense to me, but I went ahead and left my diagram ambiguous.&lt;/p&gt; &lt;p&gt;As you'll recall from the discussion of VU0, VU0 is controlled by the CPU, and VU0 gets its instructions from whatever program the CPU is currently running. VU1, however, doesn't work that way. VU1's VIF plays a much more prominent role in VU1's life than VU0's VIF does in its. VU1's VIF takes in and parses what Sony confusingly calls a &lt;b&gt;3D display list&lt;/b&gt;. This 3D display list is &lt;i&gt;not&lt;/i&gt; VU1's program. Rather, it's a data structure that contains two types of information, and some specialized commands that tell VU1 how to handle this information. The two types of info are &lt;/p&gt; &lt;p&gt;&lt;b&gt;a.&lt;/b&gt; the actual VU1 program instructions, which go in VU1's instruction memory.&lt;br /&gt;&lt;b&gt;b.&lt;/b&gt; the data that said program operates on. This goes in VU1's data memory. &lt;/p&gt;  &lt;p&gt;The VIF decodes and parses the 3D display list commands, and makes sure that VU1 program code and data find their way into the correct spots. In this manner, VU1 can operate independently of the CPU to generate display lists. Executing these VU1, &lt;b&gt;"VLIW mode"&lt;/b&gt; programs brings into play those three units that VU0 often neglects: the LSU, the iALU, and the RNG. These three units, along with the EFU (which acts as a general FPU), all function to make VU1 a full-blown SIMD/VILW coprocessor.  Hahaha...there's that term again: SIMD/VLIW. Now it's time to find out what it means.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Programming the VU&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;To wrap up, we're going to take a look at the VU's instruction format, and talk about its microarchitecture in a bit more detail. We'll look at VU1 first, because it always runs in "VLIW mode." Then we'll talk about VU0, and how it's different.&lt;/p&gt; &lt;p&gt;Both VU1 and VU0 are 2-issue, VLIW processors. The basic instruction format for VU1 is a 64-bit, VLIW instruction packet (or "bundle," or whatever VLIW term you want to use) that can be divided into two, 32-bit COP2 instructions. &lt;/p&gt; &lt;p&gt;These two instructions are executed in parallel by two execution units: the &lt;b&gt;upper execution unit &lt;/b&gt;and the &lt;b&gt;lower execution unit&lt;/b&gt;. (Refer back to the two VU block diagrams on the last page. The upper unit is blue and the lower unit is green.) These two units have the following functionality:&lt;/p&gt;  &lt;table border="0" bordercolor="#008000" width="100%"&gt;   &lt;tbody&gt;     &lt;tr&gt;       &lt;td bgcolor="#008000" width="50%"&gt;&lt;b&gt;  Upper instructions&lt;/b&gt;&lt;/td&gt;       &lt;td bgcolor="#008000" width="50%"&gt;&lt;b&gt;  Lower instructions&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;        &lt;td valign="top" width="50%"&gt;         &lt;ul&gt;&lt;li&gt;4 parallel FP ADD/SUB           &lt;/li&gt;&lt;li&gt;4 parallel FP MUL           &lt;/li&gt;&lt;li&gt;4 parallel FP ADD/MSUB           &lt;/li&gt;&lt;li&gt;4 parallel MAX/MIN           &lt;/li&gt;&lt;li&gt;Outer product calculation           &lt;/li&gt;&lt;li&gt;Clipping detection&lt;/li&gt;&lt;/ul&gt;       &lt;/td&gt;       &lt;td valign="top" width="50%"&gt;          &lt;ul&gt;&lt;li&gt;FP DIV/SQRT/RSQRT           &lt;/li&gt;&lt;li&gt;Load/Store 128b data           &lt;/li&gt;&lt;li&gt;EFU (1 FMAC + 1 FDIV)           &lt;/li&gt;&lt;li&gt;Jump/Branch           &lt;/li&gt;&lt;li&gt;Random number generator/misc&lt;/li&gt;&lt;/ul&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;  &lt;/table&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Now, what you should note is that the upper execution unit is a SIMD unit, while the lower isn't.  Hence the term "VLIW/SIMD." So the code is "64-bit VLIW," of which 32 bits are SIMD. Cool, eh? I thought so.&lt;/p&gt; &lt;p&gt;To see this in action, let's look at a code example that I've adapted from one of Sony's slides. &lt;/p&gt; &lt;table border="0" width="100%"&gt;   &lt;tbody&gt;      &lt;tr&gt;       &lt;td width="50%"&gt;&lt;b&gt;Upper Instruction&lt;/b&gt;&lt;/td&gt;       &lt;td width="50%"&gt;&lt;b&gt;Lower Instruction&lt;/b&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td bgcolor="#333333" width="50%"&gt;&lt;code&gt;MUL  VF04, VF03, Q&lt;/code&gt;&lt;/td&gt;        &lt;td bgcolor="#333333" width="50%"&gt;&lt;code&gt;DIV  Q, 1.0, VF02.w&lt;/code&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="50%"&gt;&lt;code&gt;MUL  ACC, VF10, VF01.x&lt;/code&gt;&lt;/td&gt;       &lt;td width="50%"&gt;&lt;code&gt;MOVE VF03, VF02&lt;/code&gt;&lt;/td&gt;      &lt;/tr&gt;     &lt;tr&gt;       &lt;td bgcolor="#333333" width="50%"&gt;&lt;code&gt;MADD ACC, VF11, VF01.y&lt;/code&gt;&lt;/td&gt;       &lt;td bgcolor="#333333" width="50%"&gt;&lt;code&gt;ADD  VI03M VI03, -1&lt;/code&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="50%"&gt;&lt;code&gt;MADD ACC, VF12, VF01.z&lt;/code&gt;&lt;/td&gt;        &lt;td width="50%"&gt;&lt;code&gt;NOP&lt;/code&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td bgcolor="#333333" width="50%"&gt;&lt;code&gt;MADD VF02, VF13, VF01.w&lt;/code&gt;&lt;/td&gt;       &lt;td bgcolor="#333333" width="50%"&gt;&lt;code&gt;LQ   VF01, VI01++&lt;/code&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="50%"&gt;&lt;code&gt;NOP&lt;/code&gt;&lt;/td&gt;       &lt;td width="50%"&gt;&lt;code&gt;BGTZ VI03, LOOP&lt;/code&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td bgcolor="#333333" width="50%"&gt;&lt;code&gt;NOP&lt;/code&gt;&lt;/td&gt;       &lt;td bgcolor="#333333" width="50%"&gt;&lt;code&gt;SQ   VF04, VI02++&lt;/code&gt;&lt;/td&gt;      &lt;/tr&gt;   &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;The instructions on the left are executed by the upper execution unit, while the ones on the right are executed by the lower unit.&lt;/p&gt; &lt;p&gt;VU0 is a bit different from VU1 in that, instead of operating in VLIW mode all the time, it normally runs in &lt;b&gt;"MIPS Coprocessor Mode."&lt;/b&gt; A MIPS Coprocessor instruction is a 32b instruction and not a 64-bit VLIW instruction. So this means that when it's in COP mode, VU0 can crunch 4, 32-bit FP SIMD numbers in parallel, using the 4 FMACs in the upper execution unit. (I'm assuming that in this situation, the upper opcode contains the SIMD FP instruction op and the lower opcode a NOP.)&lt;/p&gt; &lt;p&gt;VU0 doesn't have to stay in COP mode though. It can operate in VLIW mode by calling a micro-subroutine of VLIW code. In this case, it takes a 64-bit instruction bundle and splits it into two 32-bit MIPS COP2 instructions, and executes them in parallel, just like VU1.&lt;/p&gt; &lt;p&gt;As you can see, having two operating modes for VU0 is a bit complex, but it gives the unit a lot of flexibility.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;As you can see from the above breakdown, with a total of 10 FMACs, 4 FDIVs, and all the other integer, branch, and load/store resources available, the Emotion Engine is a hoss. &lt;/p&gt; &lt;p&gt;Not only does the Emotion Engine have horsepower under the hood, but its aggressively new, cutting-edge design means that it's going to take a while for developers to really learn to use all that power. It'll be interesting to see if the PC has caught up with the PS2 by the time PS2 developers figure out how to exploit this hardware to its fullest potential.&lt;/p&gt; &lt;p&gt;Although I've stated repeatedly that the PS2's number one application is 3D gaming, neither Sony nor Toshiba (Toshiba designed the Emotion Engine, and Sony licenses it) are going to sit by and let this hardware get pigeonholed in that application space. Sony has invested big, big money (I think it's around $100 million) in developing non-game applications for the PS2. So by the time the PS2 goes stateside, we should see other types of software available for it. This device is going to be the centerpiece of Sony's assault on the world's living rooms, so you can bet they'll milk it for all they can. &lt;/p&gt; &lt;p&gt;Toshiba is also planning to leverage the Emotion Engine in other markets. I don't have any details, but I'd imagine that before too long we can expect to see a whole range of devices based on this chip. As far as its options in the embedded market, it's not exactly the lowest power device available. Here are some specs that should give you an idea how it stacks up, process wise, to other CPUs out there.&lt;/p&gt; &lt;div align="center"&gt;   &lt;center&gt;   &lt;table border="0" width="85%"&gt;     &lt;tbody&gt;        &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;Clock&lt;/b&gt;&lt;/td&gt;         &lt;td width="50%"&gt;250 MHz&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;VDD&lt;/b&gt;&lt;/td&gt;         &lt;td width="50%"&gt;1.8v&lt;/td&gt;        &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;Design Rule&lt;/b&gt;&lt;/td&gt;         &lt;td width="50%"&gt;0.25 um&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;Gate Length&lt;/b&gt;&lt;/td&gt;          &lt;td width="50%"&gt;0.18 um&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;Power&lt;/b&gt;&lt;/td&gt;         &lt;td width="50%"&gt;13 watts&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;          &lt;td width="50%"&gt;&lt;b&gt;Transistors&lt;/b&gt;&lt;/td&gt;         &lt;td width="50%"&gt;10.5 million&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;Die size&lt;/b&gt;&lt;/td&gt;         &lt;td width="50%"&gt;17 mm x 14.1 mm (240 mm&lt;sup&gt;2&lt;/sup&gt;)&lt;/td&gt;        &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;Package&lt;/b&gt;&lt;/td&gt;         &lt;td width="50%"&gt;540-pin PBGA (Ball Grid Array)&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;Layers&lt;/b&gt;&lt;/td&gt;          &lt;td width="50%"&gt;4-layer metal&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;   &lt;/table&gt;   &lt;/center&gt; &lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Just to put things in perspective, 10.5 million transistors is the same number of transistors that the G4 has, with the K7 weighing in at about 22 million transistors. So while the Emotion Engine isn't exactly as svelte as &lt;a href="http://www.arstechnica.com/cpu/1q00/crusoe/crusoe-1.html"&gt;Crusoe&lt;/a&gt;, it's pretty darn lean considering all the hardware that's packed onto it. &lt;/p&gt;  &lt;p&gt;All in all, it should be a fascinating ride in the next few months as MS and Nintendo begin to ready their own console offerings. The PS2 has really upped the ante in terms of raw gaming horsepower, so MS and Nintendo are going to have to offer something killer in response. (Was I the only one who was unimpressed by the recently-released X-Box specs? I hope nVidia packs some amazing hardware into it, because after looking at the Emotion Engine, a 600MHz Intel offering ain't turnin' me on...&lt;i&gt;maybe&lt;/i&gt; if it's a Willamette...) All speculation aside though, one thing is definitely for certain. As of the Japanese launch of the Playstation 2 last month, the home entertainment scene just got much, much more exciting.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;h3&gt;Bibliography (and props)&lt;/h3&gt; &lt;p&gt;Unfortunately, none of the articles on the PS2 that I used for my research are (legally) available free of charge. I think you can get most of them via the Ask IEEE service on the web though. Speaking of docs, I want to send a big whopping &lt;b&gt;thank you&lt;/b&gt; to all the folks who responded to my recent cry for help. I've been poring over the docs in preparation for this article, and I haven't had time to write thank-you's yet. Emails will definitely be forthcoming though, because you guys made this article possible. Now, to the bibliography:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;K. Kutaragi et al., "A Micro Processor with a 128b CPU, 10     Floating-Point MACs, 4 Floating-Point Dividers, and an MPEG2 Decoder,"      ISSCC (Int’l Solid-State Circuits Conf.) Digest of Tech. Papers,Feb. 1999,     pp. 256-257.   &lt;/li&gt;&lt;li&gt;F.M. Raam et al., “A High Bandwidth Superscalar Microprocessor for     Multimedia Applications,” ISSCC Digest of Technical Papers,Feb. 1999, pp.     258-259.   &lt;/li&gt;&lt;li&gt;A. Kunimatsu et al., &lt;i&gt;5.5 GFLOPS Vector Units for “Emotion     Synthesis”&lt;/i&gt;, (Slide show and presentation.) System ULSI Engineering     Laboratory, TOSHIBA Corp. and Sony Computer Entertainment Inc.   &lt;/li&gt;&lt;li&gt;Masaaki Oka Masakazu Suzuoki. &lt;i&gt;Designing and Programming the Emotion     Engine&lt;/i&gt;, Sony Computer Entertainment. IEEE Micro, pp. 20-28   &lt;/li&gt;&lt;li&gt;Various other slides from presentations that people mailed me. I have no     idea where they came from, but if there was copyright info on them and I     used a diagram from them, I included it.   &lt;/li&gt;&lt;li&gt;Berkeley Design Technology, Inc. &lt;i&gt;&lt;a href="http://www.bdti.com/articles/multiply.htm"&gt;DSP     Processors and Cores -- the Options Multiply&lt;/a&gt;.&lt;/i&gt;  Reprinted from &lt;i&gt;Integrated     System Design&lt;/i&gt;, June, 1995   &lt;/li&gt;&lt;li&gt;Berkeley Design Technology, Inc. &lt;a href="http://www.bdti.com/articles/wpchoose.htm"&gt;Choosing     a DSP Processor&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;      &lt;/div&gt;&lt;/div&gt;&lt;br /&gt;==========================================&lt;br /&gt;&lt;b&gt;&lt;p align="center"&gt;&lt;span style="font-size:100%;"&gt;SONY     COMPUTER ENTERTAINMENT ANNOUNCES WORLD’S FASTEST 128 Bit CPU "EMOTION     ENGINE" FOR THE NEXT GENERATION PLAYSTATION&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:100%;"&gt;    &lt;/span&gt;&lt;/b&gt;&lt;p align="justify"&gt;&lt;small&gt; &lt;/small&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;TOKYO, March 2, 1999 --&lt;/b&gt; Sony Computer Entertainment Inc. is pleased to     announce the co-development with Toshiba Corp. of the 128 bit CPU ("EE", or     "Emotion EngineÔ ") for use in the next generation of PlayStationÒ . In order     to process massive multi-media information at the fastest possible speeds, data bus, cache     memory as well as all registers are 128 bits; this is integrated on a single chip LSI     together with the state of the art 0.18 micron process technology. The development of a     full 128-bit CPU is the first of its kind in the world.&lt;/span&gt;&lt;/p&gt;     &lt;span style="font-size:85%;"&gt;&lt;p align="justify"&gt;Not only will this new CPU     have application for games, but it will be the core media processor for future digital     entertainment applications, and has a vastly superior floating point calculation     capability compared to the latest personal computers. The new CPU incorporates two 64-bit     integer units (IU) with a 128-bit SIMD multi-media command unit, two independent floating     point vector calculation units (VU0, VU1), an MPEG 2 decoder circuit (Image Processing     Unit/IPU) and high performance DMA controllers onto one silicon chip. The massive combined     performance of this CPU permits complicated physical calculation, NURBS curved surface     generation and 3D geometric transformations, which are difficult to perform in real time     with PC CPUs, to be performed at high speeds.&lt;/p&gt;     &lt;p align="justify"&gt;In addition, by processing the data at     128-bits on one chip, it is possible to process and transfer massive volumes of     multi-media data. CPUs on conventional PCs have a basic data structure of 64 bits, with     only 32 bits on recent game consoles. The main memory supporting the high speed CPU uses     the Direct Rambus DRAM in two channels to achieve a 3.2GB/second bus bandwidth. This     equates to four times the performance of the latest PCs that are built on the PC-100     architecture.&lt;/p&gt;     &lt;p align="justify"&gt;By incorporating the MPEG 2 decoder     circuitry on one chip, it is now possible to simultaneously process high-resolution 3D     graphics data at the same time as high quality DVD images. The combination of the two     allows the introduction of a new approach to digital entertainment and real-time graphics     and audio processing.&lt;/p&gt;     &lt;p align="justify"&gt;With a floating point calculation     performance of 6.2GFLOPS/second, the overall calculation performance of this new CPU     matches that of a super computer. When this is applied to the processing of geometric and     perspective transformations normally used in the calculation of 3D computer graphics     (3DCG), the peak calculation performance reaches 66 million polygons per second. This     performance is comparable with that of high-end graphics workstations (GWS) used in motion     picture production.&lt;/p&gt;     &lt;/span&gt;&lt;p align="justify"&gt;&lt;span style="font-size:78%;"&gt;Rambus is a     registered trademark of Rambus Inc.&lt;/span&gt;&lt;/p&gt;     &lt;p align="justify"&gt;&lt;span style="font-size:85%;"&gt;&lt;u&gt;&lt;b&gt;Emotion Engine     Features and General Specifications&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;     &lt;span style="font-size:85%;"&gt;&lt;p align="justify"&gt;CPU core 128bit RISC (MIPS     IV-subset)&lt;/p&gt;     &lt;p align="justify"&gt;Clock Frequency 300MHz&lt;/p&gt;     &lt;p align="justify"&gt;Integer Unit 64bit (2-way Superscalar)&lt;/p&gt;     &lt;p align="justify"&gt;Multimedia extended instructions 107     instructions at 128bit width&lt;/p&gt;     &lt;p align="justify"&gt;Integer General Purpose Register 32 at 128     bit width&lt;/p&gt;     &lt;p align="justify"&gt;TLB 48 double entries&lt;/p&gt;     &lt;p align="justify"&gt;Instruction Cache 16KB (2-way)&lt;/p&gt;     &lt;p align="justify"&gt;Data Cache 8KB (2-way)&lt;/p&gt;     &lt;p align="justify"&gt;Scratch Pad RAM 16KB (Dual port)&lt;/p&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p align="justify"&gt;=================================&lt;br /&gt;&lt;/p&gt;     &lt;p align="justify"&gt;Main Memory 32MB (Direct RDRAM 2ch@800MHz)&lt;/p&gt;     &lt;p align="justify"&gt;Memory bandwidth 3.2GB/sec&lt;/p&gt;     &lt;p align="justify"&gt;DMA 10 channels&lt;/p&gt;     &lt;p align="justify"&gt;Co-processor1 FPU (FMAC x 1, FDIV x 1)&lt;/p&gt;     &lt;p align="justify"&gt;Co-processor2 VU0 (FMAC x 4, FDIV x 1)&lt;/p&gt;     &lt;p align="justify"&gt;Vector Processing Unit VU1 (FMAC x 5, FDIV     x 2)&lt;/p&gt;     &lt;p align="justify"&gt;Floating Point Performance 6.2GFLOPS&lt;/p&gt;     &lt;p align="justify"&gt;Geometry &lt;/p&gt;     &lt;p align="justify"&gt;+ Perspective Transformation 66Million     Polygons/sec&lt;/p&gt;     &lt;p align="justify"&gt;+ Lighting 38Million Polygons/sec&lt;/p&gt;     &lt;p align="justify"&gt;+ Fog 36Million Polygons/sec&lt;/p&gt;     &lt;p align="justify"&gt;Curved Surface Generation (Bezier)     16Million Polygons/sec&lt;/p&gt;     &lt;p align="justify"&gt;Image Processing Unit MPEG2 Macroblock     Layer Decoder&lt;/p&gt;     &lt;p align="justify"&gt;Image Processing Performance 150Million     Pixels/sec&lt;/p&gt;     &lt;p align="justify"&gt;Gate width 0.18 micron&lt;/p&gt;     &lt;p align="justify"&gt;VDD Voltage 1.8 V&lt;/p&gt;     &lt;p align="justify"&gt;Power Consumption 15 Watts&lt;/p&gt;     &lt;p align="justify"&gt;Metal Layers 4&lt;/p&gt;     &lt;p align="justify"&gt;Total Transistors 10.5 Million&lt;/p&gt;     &lt;p align="justify"&gt;Die Size 240 mm&lt;sup&gt;2&lt;/sup&gt;&lt;/p&gt;     &lt;p align="justify"&gt;Package 540pin PBGA&lt;/p&gt;     &lt;/span&gt;&lt;p align="center"&gt; &lt;/p&gt;     &lt;p align="center"&gt;&lt;span style="font-size:78%;"&gt;&lt;img src="http://arstechnica.com/cpu/1q99/image7.gif" height="303" width="565" /&gt;&lt;/span&gt;&lt;/p&gt;     &lt;p align="justify"&gt; &lt;/p&gt;     &lt;span style="font-size:78%;"&gt;&lt;p align="center"&gt;&lt;img src="http://arstechnica.com/cpu/1q99/image8.gif" height="303" width="565" /&gt;&lt;/p&gt;     &lt;/span&gt;&lt;blockquote&gt;       &lt;p align="justify"&gt;&lt;span style="font-size:78%;"&gt;*) 4 dimensional       calculation to single precision floating point.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:78%;"&gt;      &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:78%;"&gt;EE performance based on measured data. For P2 and P3,       theoretical maximum values based on manufacturer’s figures and other published data.&lt;/span&gt;&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;     &lt;/blockquote&gt;=================================&lt;br /&gt;&lt;p align="center"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;SONY COMPUTER     ENTERTAINMENT ANNOUNCES THE DEVELOPMENT OF THE WORLD’S FASTEST GRAPHICS RENDERING     PROCESSOR USING EMBEDDED DRAM TECHNOLOGY&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;b&gt;    &lt;/b&gt;&lt;p align="justify"&gt;&lt;b&gt;&lt;span style="font-size:85%;"&gt;TOKYO, March 2, 1999 --&lt;/span&gt;&lt;/b&gt; &lt;span style="font-size:85%;"&gt;    Sony Computer Entertainment has developed the Graphics Synthesizer for the next generation     PlayStation&lt;sup&gt;®&lt;/sup&gt; incorporating a massively parallel rendering engine that contains     a 2,560 bit wide data bus that is 20 times the size of leading PC-based graphics     accelerators. Very high pixel fill rates and drawing performance is achieved only through     the use of embedded DRAM process technology pioneered by SCE for use in advanced graphics     technology.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p align="justify"&gt;&lt;span style="font-size:85%;"&gt;The current PlayStation introduced the     concept of the Graphics Synthesizer via the real-time calculation and rendering of a 3D     object. This new GS rendering processor is the ultimate incarnation of this concept –     delivering unrivalled graphics performance and capability. The rendering function was     enhanced to generate image data that supports NTSC/PAL Television, High Definition Digital     TV and VESA output standards. The quality of the resulting screen image is comparable to     movie-quality 3D graphics in real time.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p align="justify"&gt;&lt;span style="font-size:85%;"&gt;In the design of graphics systems, the     rendering capability is defined by the memory bandwidth between the pixel engine and the     video memory. Conventional systems use external VRAM reached via an off-chip bus that     limits the total performance of the system. However in the case of the new GS, there is a     48-Gigabyte memory access bandwidth achieved via the integration of the pixel logic and     the video memory on a single high performance chip. This allows orders of magnitude     greater pixel fill-rate performance compared to today’s best PC-based graphics     accelerators.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p align="justify"&gt;&lt;span style="font-size:85%;"&gt;When rendering small polygons, the peak     drawing capacity is 75 Million polygons per second and the system can render 150 Million     particles per second. With this large drawing capability, it is possible to render a     movie-quality image. With Z-buffering, textures, lighting and alpha blending     (transparency), a sustained rate of 20 Million polygons per second can be drawn     continuously.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p align="justify"&gt;&lt;span style="font-size:85%;"&gt;This new architecture can also execute     recursive multi-pass rendering processing and filter operations at a very fast speed     without the assistance of the main CPU or main bus access. In the past, this level of     real-time performance was only achieved when using very expensive, high performance,     dedicated graphics workstations. However, with the design of the new Graphics Synthesizer,     this high quality image is now available for in-home computer entertainment applications.     This will help accelerate the convergence of movies, music and computer technology into a     new form of digital entertainment.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;u&gt;&lt;b&gt;Graphics Synthesizer – Features and General     Specifications&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;GS Core Parallel Rendering Processor with embedded DRAM&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Clock Frequency 150 MHz&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;No. of Pixel Engines 16 (in Parallel)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Embedded DRAM 4 MB of multi-port DRAM (Synced at 150MHz)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Total Memory Bandwidth 48 Giga Bytes per Second&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Combined Internal&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Data Bus bandwidth 2560 bit&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Read 1024 bit&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Write 1024 bit&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Texture 512 bit&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Display Color Depth 32 bit (RGBA: 8 bits each)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Z Buffering 32 bit &lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Rendering Functions Texture Mapping, Bump Mapping&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Fogging, Alpha Blending&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Bi- and Tri-Linear Filtering&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;MIPMAP, Anti-aliasing&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Multi-pass Rendering&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;Rendering Performance&lt;/b&gt;&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Pixel Fill Rate 2.4 Giga Pixel per Second &lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;(with Z buffer and Alphablend enabled)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;1.2 Giga Pixel per Second &lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;(with Z buffer, Alpha and Texture)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Particle Drawing Rate 150 Million /sec&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Polygon Drawing Rate 75 Million /sec (small polygon)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;50 Million /sec (48 Pixel quad with Z and A)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;30 Million /sec (50 Pixel triangle with Z and A)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;25 Million /sec (48 Pixel quad with Z, A and T)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Sprite Drawing Rate 18.75 Million (8 x 8 Pixels)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;Display output&lt;/b&gt; NTSC/PAL&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Digital TV (DTV)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;VESA (maximum 1280 x 1024 pixels)&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Silicon process technology 0.25 µ 4-level metal&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Total number of transistors 43 Million &lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Die size 279mm&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Package Type: 384 pin BGA&lt;/span&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;span style="font-size:85%;"&gt;&lt;img src="http://arstechnica.com/cpu/1q99/image9.gif" height="303" width="566" /&gt;&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p align="center"&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p align="center"&gt;&lt;span style="font-size:85%;"&gt;&lt;img src="http://arstechnica.com/cpu/1q99/image10.gif" height="303" width="566" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;===========================&lt;br /&gt;&lt;p align="center"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;SONY COMPUTER     ENTERTAINMENT ANNOUNCES THE DEVELOPMENT OF AN I/O PROCESSOR FOR THE NEXT GENERATION     PLAYSTATION&lt;sup&gt;®&lt;/sup&gt; THAT PROVIDES 100% BACKWARDS COMPATIBILITY&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;b&gt;    &lt;/b&gt;&lt;p align="justify"&gt;&lt;b&gt;&lt;span style="font-size:85%;"&gt;TOKYO, March 2, 1999 --&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:85%;"&gt; Sony     Computer Entertainment has developed the I/O Processor with LSI Logic Corporation for the     next generation PlayStation. By embedding this processor we have achieved 100% backward     compatibility with the current PlayStation. In addition, the new I/O Processor supports     IEEE 1394 and Universal Serial Bus (USB) which are the new standards for digital     interconnectivity.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p align="justify"&gt;&lt;span style="font-size:85%;"&gt;The new I/O Processor for the next generation     PlayStation is based on the current PlayStation CPU but with enhanced cache memory and a     new, higher performance DMA architecture that permits a four-fold increase in data     transfer rates. The serial interface is also upgraded to over 20 times the performance of     the current PlayStation. In addition, the USB host controller and the IEEE 1394 link and     physical layers are integrated onto this single chip LSI.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;p align="justify"&gt;&lt;span style="font-size:85%;"&gt;The USB interface is compatible with OHCI (Open Host     Controller Interface) and can handle data transfer rates of between 1.5Mbps and 12Mbps     (Mega bits per second). IEEE 1394 can handle data transfer rates of between 100 Mbps and     400 Mbps.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;span style="font-size:85%;"&gt;The use of these interfaces allows the future     connectivity of the new PlayStation system to a variety of other systems and consumer     products such as VCR, Set Top Box, Digital Camera, Printer, Joystick, Keyboard and Mouse     amongst others.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-3871224526468965929?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/3871224526468965929/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=3871224526468965929' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3871224526468965929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3871224526468965929'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/05/sound-and-vision-technical-overview-of.html' title='Sound and Vision: A Technical Overview of the Emotion Engine'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-1941179587335832188</id><published>2008-05-09T08:18:00.000-07:00</published><updated>2008-05-09T08:21:12.284-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/計算機'/><title type='text'>SIMD architectures</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;    By &lt;/span&gt;&lt;a style="font-family: courier new;" href="http://arstechnica.com/authors.ars/hannibal"&gt;Jon Stokes&lt;/a&gt;&lt;span style="font-family: courier new;"&gt; |     Published: March 21, 2000 - 07:00PM CT&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2 style="font-family: courier new;"&gt;Introduction&lt;/h2&gt;      &lt;div style="font-family: courier new;" class="Body"&gt;      &lt;p&gt;What do Sony's Playstation2 and Motorola's MPC7400 (a.k.a. the G4) have in common?  Besides the incredible hype behind both products and their legions of crazed fans, there's one acronym that unites them all--an acronym that sums up the secret to their stellar performance: SIMD.  Single Instruction stream, Multiple Data streams (SIMD) computing first entered the personal computing world in the form of Intel's neglected addition to the x86 instruction set, MMX.  Even though MMX was panned by the press and was slow to be adopted, SIMD computing was here to stay on the personal computing landscape.  And it's a good thing too, because SIMD is a technology whose time has definitely come, and it's just about ubiquitous on the desktop: MMX, SSE, 3DNow!, AltiVec, etc. are all acronyms for SIMD instruction sets. In this article, we're going to look at what SIMD &lt;i&gt;is&lt;/i&gt;, what it &lt;i&gt;offers&lt;/i&gt;, and how it's &lt;i&gt; integrated&lt;/i&gt; in three-and-a-half of today's hottest processors.  Three and a half?  The half is Sun's upcoming &lt;a href="http://arstechnica.com/articles/paedia/4q99/majc/majc-1.html"&gt; MAJC architecture&lt;/a&gt;, which isn't actually out yet.  We've included it here because its approach to SIMD is quite different from the other three, so it provides a nice contrast. &lt;/p&gt;       &lt;p&gt;This article will provide       a basic introduction to SIMD concepts, as well as an overview of the three       and a half SIMD implementations under discussion.  One thing that       should definitely be understood is that this article is actually the       sequel to my previous &lt;a href="http://arstechnica.com/articles/paedia/cpu/g4vsk7/g4vsk7-1.html"&gt;G4 vs. K7&lt;/a&gt; tech       article.  If you want to look at AltiVec and 3DNow! in the context of       both the G4 and K7 as a whole, then you &lt;i&gt;must&lt;/i&gt; read the first article       too.  This article focuses in on the SIMD, and ignores many of the       important issues already taken up by its predecessor.&lt;/p&gt;       &lt;p&gt;  &lt;/p&gt; &lt;h2&gt;SIMD basics&lt;/h2&gt; &lt;p&gt;Early microprocessors didn't actually have any floating-point capabilities; they were strictly integer crunchers.  Floating-point calculations were done on separate, dedicated hardware, usually in the form of a math coprocessor.  Before long though, transistor sizes shrunk to the point where it became feasible to put a floating-point unit directly onto the main CPU die, and the modern integer/floating-point microprocessor was born.  Of course, the addition of floating-point &lt;i&gt; hardware&lt;/i&gt; meant the addition of floating-point &lt;i&gt;instructions&lt;/i&gt;.  For the x86 world, this meant the introduction of the x87 floating-point architecture and its (now hopelessly archaic) stack-based register model.&lt;/p&gt; &lt;p&gt;So the x87 brought a new name, new capabilities, new registers, and new instructions to Intel's microprocessors.  Sound familiar?  It should.&lt;/p&gt;       &lt;p&gt;Actually, the addition of SIMD instructions and hardware to a modern, superscalar CPU is a bit more drastic than the addition of floating-point capability.  A microprocessor is a SISD device (Single Instruction stream, Single Data stream), and it has been since its inception.  &lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/1q00/simd/figure6.gif" border="0" height="292" width="401" /&gt;&lt;/div&gt;  &lt;p&gt;As you can see from the above picture, a SIMD machine exploits a property of the data stream called &lt;b&gt; data parallelism&lt;/b&gt;.  You get data parallelism when you have a large mass of data of a uniform type that needs the same instruction performed on it.  A classic example of data parallelism is inverting an RGB picture to produce its negative.  You have to iterate through an array of uniform integer values (pixels), and perform the same operation (inversion) on each one -- multiple data points, a single operation.  Modern, superscalar SISD machines exploit a property of the &lt;i&gt; instruction stream&lt;/i&gt; called &lt;b&gt; instruction-level parallelism&lt;/b&gt;  (ILP).  In a nutshell, this means that you execute multiple instructions at once on the same data stream.  (See &lt;a href="http://arstechnica.com/articles/paedia/index.html"&gt; my other articles&lt;/a&gt; for more detailed &lt;a href="http://arstechnica.com/cpu/4q99/majc/majc-2.html"&gt; discussions of ILP&lt;/a&gt;).  So a SIMD machine is a different class of machine than a normal microprocessor.  SIMD is about exploiting parallelism in the data stream, while superscalar SISD is about exploiting parallelism in the instruction stream.&lt;/p&gt; &lt;p&gt;There were some early, ill-fated attempts at making a &lt;i&gt; purely&lt;/i&gt; SIMD machine (i.e., a SIMD-only machine).  The problem with these attempts is that the SIMD model is simply not flexible enough to accoodate general purpose code.  The only form in which SIMD is really feasible is as a part of a SISD host machine that can execute conditional instructions and other types of code that SIMD doesn't handle well.  This is, in fact, the situation with SIMD in today's market.  Programs are written for a SISD machine, and include in their code SIMD instructions.&lt;/p&gt;       &lt;p&gt;One thing I'd like to       note for the sake of all you nit-pickers out there, is that I'm going by       the description of SISD as laid out in &lt;a href="http://arstechnica.com/articles/etc/books/comp-arc.html"&gt; Hennessey and       Patterson&lt;/a&gt;.  A       more detailed discussion of the finer points of SISD vs. SIMD as concepts,       while it would be appropriate here, would hinder us from moving more       quickly to the actual comparison of the SIMD implementations.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;SIMD operations&lt;/h2&gt;            &lt;p&gt;The basic unit of SIMD love is the &lt;i&gt;vector&lt;/i&gt;, which is why SIMD computing is also known as vector processing.  A vector is nothing more than a row of individual numbers, or scalars.&lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/1q00/simd/figure7.gif" border="0" height="286" width="263" /&gt;&lt;/div&gt; &lt;p&gt;A regular CPU operates on scalars, one at a time.  (A superscalar CPU operates on multiple scalars at once, but it performs a different operation on each instruction.)  A vector processor, on the other hand, lines up a whole row of these scalars, all of the same type, and operates on them as a unit.  &lt;/p&gt; &lt;p&gt;These vectors are represented in what is called &lt;b&gt;packed data format&lt;/b&gt;.  Data are grouped into bytes (8 bits) or words (16 bits), and packed into a vector to be operated on.  One of the biggest issues in designing a SIMD implementation is how many data elements will it be able to operate on in parallel.  If you want to do single-precision (32-bit) floating-point calculations in parallel, then you can use a 4-element, 128-bit vector to do four-way single-precision floating-point, or you can use a 2-element 64-bit vector to do two-way SP FP.  So the length of the individual vectors dictates how many elements of what type of data you can work with.&lt;/p&gt; &lt;p&gt;Motorola's AltiVec literature divides into four useful and easily comprehendible categories the types of SIMD operations that AltiVec can do.  These categories are a good way of dividing up the basic things you can do with vectors.  Unfortunately for people who write SIMD comparison articles, both AMD's and Intel's tech docs categorize their hardware's SIMD operations in a completely different and less accessible way.  (Actually, Intel's tech docs categorize things one way, and AMD's tech docs copy Intel's categorization.  It's good to see that at least Motorola can think different&lt;span style="color:#808080;"&gt;&lt;strike&gt;ly&lt;/strike&gt;&lt;/span&gt;.)  I'm going to use Motorola's categories, at least initially, for tutorial purposes.  I'm also going to rob some of Motorola's pictures out of their AltiVec literature, and modify them a bit.  &lt;/p&gt; &lt;h3&gt;I.  Intra element arithmetic and non-arithmetic functions.&lt;/h3&gt; &lt;p&gt; &lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/1q00/simd/figure2.gif" border="0" height="196" width="469" /&gt;&lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Intra-element arithmetic is one of the most basic and obvious types of SIMD operation.  Consider an intra-element addition.  This involves lining up two vectors (VA and VB), and adding their individual elements together to produce a sum vector (VT). The above picture shows an example of inter-element arithmetic at work. Inter-element operations also include multiplication, multiply-add, average, and min.&lt;/p&gt; &lt;p&gt;Intra-element non-arithmetic functions basically work the same as above, except for the fact the operations performed are different.  Intra-element non-arithmetic operations include AND, OR, and XOR.&lt;/p&gt; &lt;div align="center"&gt;   &lt;center&gt;   &lt;table border="1" bordercolor="#007700" width="50%"&gt;     &lt;tbody&gt;&lt;tr&gt;       &lt;td bgcolor="#007700" width="100%"&gt;         &lt;p align="center"&gt;Vector intra element instructions&lt;/p&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="100%"&gt;         &lt;ul&gt;&lt;li&gt;integer instructions&lt;/li&gt;&lt;li&gt;integer arithmetic instructions&lt;/li&gt;&lt;li&gt;integer compare instructions&lt;/li&gt;&lt;li&gt;integer rotate and shift instructions&lt;/li&gt;&lt;li&gt;floating-point instructions&lt;/li&gt;&lt;li&gt;floating-point arithmetic instructions&lt;/li&gt;&lt;li&gt;floating-point rounding and conversion instructions&lt;/li&gt;&lt;li&gt;floating-point compare instruction&lt;/li&gt;&lt;li&gt;floating-point estimate instructions&lt;/li&gt;&lt;li&gt;memory access instructions&lt;/li&gt;&lt;/ul&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;   &lt;/center&gt; &lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;h3&gt;II.  Inter Element Arithmetic&lt;/h3&gt; &lt;p&gt; &lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/1q00/simd/figure2.2.gif" border="0" height="215" width="407" /&gt;&lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Inter-element operations are operations that happen between the elements in a single vector.  An example of an inter-element arithmetic operation is shown above.  This operation sums across the elements in a vector, and stores the result in an accumulation vector.&lt;/p&gt; &lt;h3&gt;IV.  Inter Element Non-arithmetic&lt;/h3&gt; &lt;p&gt;Inter-element non-arithmetic operations are operations like vector permute, which rearrange the order of the elements in an individual vector.  We'll look at the permute operation a little closer in a later section.&lt;/p&gt;         &lt;table border="1" bordercolor="#007700" width="50%"&gt;&lt;tbody&gt;&lt;tr&gt;       &lt;td bgcolor="#007700" width="100%"&gt;         &lt;p align="center"&gt;Vector inter element instructions&lt;/p&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td width="100%"&gt;         &lt;ul&gt;&lt;li&gt;alignment support instructions &lt;/li&gt;&lt;li&gt;permutation and formatting instructions &lt;/li&gt;&lt;li&gt;pack instructions &lt;/li&gt;&lt;li&gt;unpack instructions &lt;/li&gt;&lt;li&gt;merge instructions &lt;/li&gt;&lt;li&gt;splat instructions &lt;/li&gt;&lt;li&gt;permute instructions &lt;/li&gt;&lt;li&gt;shift left/right instructions&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2 style="font-family: courier new;"&gt;Saturated arithmetic&lt;/h2&gt;      &lt;div style="font-family: courier new;" class="Body"&gt;      &lt;p&gt;One feature that all the       SIMD implementations under discussion share is support for &lt;b&gt;saturated       arithmetic&lt;/b&gt;. With wrap-around arithmetic, whenever you do a       calculation whose result turns out to be bigger than what you can       represent with whatever data format you're using (16-bit, 32-bit, etc.),       the CPU stores a wrap-around number in the destination register and sets       some sort of overflow flag to tell the program that the value exceeded its       limits.  This isn't really ideal for media applications though.        If you add two 32-bit color pixel values together and get a number that's       greater than what you can represent with 32-bits, you just want the result       to come out as the maximum represent able value (#FFFFFF, or white).        You don't really care that the number was too big; you just want to       represent the extreme value.  It's sort of like turning up the volume       on an amplifier past 10 (Spinal Tap jokes aside).  You can keep on       turning that knob, but the amp is already maxed out--which is what you       want.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;h2&gt;AltiVec&lt;/h2&gt;       &lt;p&gt;I'll start my description       of SIMD implementations with AltiVec, because of its simplicity and straightforward       design.  Even though Intel's and AMD's SIMD implementations came &lt;i&gt;       before&lt;/i&gt; AltiVec chronologically, I'll use AltiVec as the norm and treat the       other two as deviations.  I do this mainly for didactic purposes; it       makes the material easier to understand.  &lt;/p&gt;       &lt;p&gt;Unlike AMD and Intel,       Motorola took a dedicated hardware approach to SIMD.  They added 32       new AltiVec registers to the G4's die along with two dedicated AltiVec       SIMD functional units, thus increasing the die size of the G4.  Nevertheless, the G4's die is       still under 1/3 the size of the PIII's, which is itself about half the       size of the Athlon's.  Since the G3 was so small to begin with (in       comparison to Intel's and AMD's offerings), Motorola could afford to spend       the extra transistors adding dedicated SIMD hardware.&lt;/p&gt;       &lt;p&gt;All of the AltiVec       calculations are done by one of two fully-pipelined, independent AltiVec       execution units.  The first unit is the Vector Permute Unit.  It       handles vector operations that involve rearranging the order of the       elements in a vector.  These are those inter-element operations, like       pack, unpack, and permute. It also handles vector memory accesses -- the       loading and storing of vectors into the registers. &lt;/p&gt;       &lt;p&gt; The second piece of hardware is the Vector ALU.        This unit handles all of the vector arithmetic (integer and FP multiply, add, etc.) and       logic (AND, OR, XOR, etc.) operations.  Most of these fall under the       heading of intra-element operations, where you're combining two vectors       (and possibly a control vector) to get a result.&lt;/p&gt;       &lt;p&gt;Both of these execution       units are fully pipelined and independent.  This means that the G4       can execute two 128-bit vector operations per cycle (one ALU, one       permute), and it can do so in parallel with regular floating-point       operations and integer operations.  The units are also pretty fast.  The instruction latency is 1 cycle for simple       operations, and 3-4 cycles for more complex ones.&lt;/p&gt;       &lt;p&gt;As I noted above, AltiVec       has 32 architectural SIMD registers.  This is a lot of registers, and       they really give the compiler freedom to schedule operations and manage       register usage for maximum efficiency.  Each register is 128 bits wide, which means       that AltiVec can operate on vectors that are 128 bits wide.        AltiVec's 128-bit wide vectors can be subdivided into&lt;/p&gt;       &lt;ul&gt;&lt;li&gt;16 elements, where           each element is either an 8-bit signed or unsigned integer, or an           8-bit character.&lt;/li&gt;&lt;li&gt;8 elements, where each           element is a 16-bit signed or unsigned integer&lt;/li&gt;&lt;li&gt;4 elements, where each           element is a either a 32-bit signed or unsigned integer, or a single           precision (32-bit) IEEE floating-point number.&lt;/li&gt;&lt;/ul&gt;       &lt;p&gt;That last bullet point is       especially important to note.  The ability to grind through vectors       of four, single precision floating-point numbers every cycle is       impressive, and represents a key advantage of AltiVec.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;h2&gt;Instructions&lt;/h2&gt;       &lt;p&gt;AltiVec adds 162 new       instructions to the G4's instruction set.  The AltiVec instruction       format is especially nice, as it allows you to use 4 distinct registers to       do your computations: two source registers to hold the operands, 1       filter/modifier register, and 1 destination register to hold the result.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/1q00/simd/figure1.gif" border="0" height="196" width="469" /&gt;&lt;/div&gt;       &lt;p&gt; &lt;/p&gt;       &lt;p&gt;The diagram above shows a       basic, intra-element operation.  VA and VB are the source registers,       and VC is a filter/modifier register that can hold masks, or otherwise       modify a computation. VT is the destination register.&lt;/p&gt;       &lt;p&gt;The filter/mod register       adds a lot of flexibility, especially when you're doing something like a       vector permute.&lt;/p&gt;       &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/1q00/simd/figure3.gif" border="0" height="322" width="448" /&gt;&lt;/div&gt;       &lt;p&gt; &lt;/p&gt;       &lt;p&gt;In the picture above, VA       and VB contain the two vectors to be permuted, and VC contains the control       vector that tells AltiVec which elements it should put where. &lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;h2&gt;Interrupts&lt;/h2&gt;       &lt;p&gt;Another important       advantage of AltiVec that deserves to be pointed out is that there are no       interrupts except on vector LOADs and STOREs.  You have to have       interrupts for LOADs and STOREs in case of, for instance, a cache       miss.  If AltiVec tries to LOAD some data from the L1 cache into a       register, and that data isn't there, it throws an interrupt (stops       executing) so that it can wait for the data to arrive.&lt;/p&gt;       &lt;p&gt;AltiVec doesn't, however,       have interrupts for things like overflows and such (remember the saturated       arithmetic discussion).  Furthermore, the peculiar implementation       that 3DNow! and SSE use to do 128-bit single-precision FP means that a       128-bit fp calculation can throw an interrupt, saturation or no.        More on that when we talk about SSE, though.&lt;/p&gt;       &lt;p&gt;The upshot of all this is       that AltiVec can keep up its single-cycle throughput as long as the L1       keeps the data stream full.  The FP and integer instructions aren't       going to hold up execution by throwing an interrupt.&lt;/p&gt;      &lt;/div&gt;&lt;br /&gt;&lt;h2 style="font-family: courier new;"&gt;The Story of MMX&lt;/h2&gt;      &lt;div style="font-family: courier new;" class="Body"&gt;      &lt;p&gt;The story of MMX and SSE/KNI/MMX2       is quite a bit more complicated than AltiVec's. There are a number of       reasons why this is so. To begin with, Intel introduced MMX first as an       integer-only SIMD solution. MMX doesn't support floating-point arithmetic       at all. Even as MMX was being rolled out, Intel knew that they had to       include FP support at some point. An article in &lt;a href="http://developer.intel.com/technology/itj/q21999.htm"&gt; an issue&lt;/a&gt; of the Intel       Technology Journal tells this story:&lt;/p&gt; &lt;blockquote&gt;      &lt;p&gt;In February 1996,       the product definition team at Intel presented Intel's executive staff       with a proposal for a single-instruction-multiple-data (SIMD) floating       point model as an extension to IA-32 architecture. In other words, the       "Katmai" processor, later to be externally named the Pentium III       processor, was being proposed. The meeting was inconclusive. At that time,       the PentiumÆ processor with MMX instructions had not been introduced and       hence was unproven in the market. Here the executive staff were being       asked essentially to "double down" their bets on MMX       instructions and then on SIMD floating point extensions. Intel's executive       staff gave the product team additional questions to answer and two weeks       later, still in February 1996, they gave the OK for the "Katmai"       processor project. During the later definition phase, the technology focus       was refined beyond 3D to include other application areas such as audio,       video, speech recognition and even server application performance. In       Febuary 1999, the Pentium III processor was introduced.&lt;/p&gt;&lt;/blockquote&gt;       &lt;p&gt;Another complicating       factor for MMX is the fact that Intel jumped through some hoops to avoid       adding a new processor state, hoops that complicated the implementation of       MMX. I'll deal with this in more detail shortly.&lt;/p&gt;       &lt;p&gt;Instead of discussing MMX       and SSE together, I'll first discuss MMX alone. This will lay the       groundwork for the discussion of both SSE and 3DNow!, since they're both       expansions of MMX, and competitors to boot.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;h2&gt;The elements&lt;/h2&gt;       &lt;p&gt;I'll save a discussion of       MMX's implementation on the PIII and its attendant problems for the       section on SSE.  For now, let's consider some basic features of MMX       as an instruction set. Where AltiVec's vectors       are 128 bits wide, MMX's are only 64 bits wide. These 64-bit vectors can       be subdivided into &lt;/p&gt;       &lt;ul&gt;&lt;li&gt;8 elements (a packed           byte), where each element is a 8-bit integer, &lt;/li&gt;&lt;li&gt; 4 elements (a packed           word), where each element is a 16-bit signed or       unsigned integer, or &lt;/li&gt;&lt;li&gt;2 elements (packed double           word), where each element is a 32-bit signed or unsigned           integer. &lt;/li&gt;&lt;/ul&gt;       &lt;p&gt; These vectors are stored in 8 MMX registers,       based on a flat file model. These 8 registers, MM0-MM7, are aliased onto       the x87's stack-based floating-point registers, FP0-FP7. Intel did this in       order to avoid imposing a costly state switch any time you want to use MMX       instructions. The drawback to this approach is that floating-point       operations and MMX operations must share a register space, so a programmer       can't mix floating-point and MMX instructions in the same routine. Of       course, since there's no mode bit for MMX or FP, there's nothing to       prevent a programmer from pulling such a stunt and corrupting his       floating-point data.&lt;/p&gt;       &lt;p&gt;The fact that you can't       mix floating-point and MMX instructions normally isn't a problem, though.       In most programs, floating-point calculations are used for generating       data, while SIMD calculations are used for displaying it.&lt;/p&gt;       &lt;p&gt;In all, MMX added 57 new       instructions to the x86 ISA. The MMX instruction format is pretty much like       the conventional x86 instruction format:&lt;/p&gt;       &lt;p align="center"&gt;&lt;b&gt;MMX Instruction mmreg1,       mmreg2&lt;/b&gt;&lt;/p&gt;       &lt;p&gt;In the above instruction,       mmreg1 is the both the destination and source operand, meaning that mmreg1       gets overwritten by the result of the calculation.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/1q00/simd/figure4.gif" border="0" height="136" width="284" /&gt;&lt;/div&gt;       &lt;p&gt; &lt;/p&gt;       &lt;p&gt;For obvious reasons, this       situation isn't nearly as optimal as AltiVec's. If you perform an MMX op       and then immediately afterwards need one of the source vectors again,       you're SOL. Either you made a backup copy of it in another register       beforehand, or you've got to reload it; both options take extra time and       hinder performance.&lt;/p&gt;       &lt;p&gt;Another thing that makes       the MMX instruction format less cool is that MMX operations lack that       third filter/mod vector that AltiVec has. This means that you just can't       do those once-cycle, arbitrary two-vector permutes. Oh well...&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Sequel: MMX2/SSE/KNI&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;If you thought that MMX       was hobbled by backwards compatibility issues, wait until you get a load       of SSE (the ISA extension formerly known as MMX2/KNI). Intel's goal with       SSE was to add four-way, 128-bit SIMD single-precision floating-point       computation to the x86 ISA. Did they succeed? Well, sorta.&lt;/p&gt;       &lt;p&gt;With the PIII, Intel went       halfway on adding dedicated hardware to the CPU die. The PIII has two,       fully-pipelined, independent, SIMD, single-precision floating-point units       (that's a mouthful). However, for SIMD floating-point multiplication, they       expanded on the existing FP multiplier hardware. So SIMD FP       multiplications share an execution unit with regular FP multiplications.       The PIII does, in fact, have a dedicated SIMD FP adder, which is       independent of the regular floating-point hardware.&lt;/p&gt;       &lt;p&gt;As far as the registers,       Intel went ahead and added an extra 8, 128-bit registers for holding SIMD       floating-point instructions. These eight are in addition to the 8 MMX/x87       registers that were already there. Since these registers are totally new       and independent, Intel had to hold their nose and add an extra processor       state to accommodate them. This means a state switch if you want to go       from using x87 to MMX or SSE. It also means that OS code had to be rewritten to accommodate the new       state.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/1q00/simd/figure9.1.gif" border="0" height="236" width="417" /&gt;&lt;/div&gt;       &lt;p&gt; &lt;/p&gt;       &lt;p&gt;Now, when I said that       Intel "sorta" succeeded in adding four-way, 128-bit SIMD FP to       the x86 ISA, I meant that the way the PIII handles it is kind of a hack.       See, a 4-way FP SSE instruction gets broken down into two, 2-way (64-bit)       microinstructions. These instructions are then executed either in parallel       or sequentially by the       two SIMD units. "Wait a minute," you object. "Doesn't one       SIMD unit do addition and the other do multiplication?" Yeah, that's       the case. So what this means for sustained 128-bit computation with 1       op/cycle throughput is that you can only       do it with floating-point multiply-add instructions. These instructions       show up in dot product calculations, so they're pretty common. Still, it's       not as cool as being able to do just any 128-bit vector calculation you       like at 1 op/cycle.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/1q00/simd/figure8.gif" border="0" height="329" width="498" /&gt;&lt;/div&gt;       &lt;p&gt; &lt;/p&gt;       &lt;p&gt;Intel made this decision       for a number of reasons. First and foremost, they wanted to conserve die       space. As it is, MMX/SSE adds 10% to the size of the PIII's die. If they       had gone ahead and implemented an independent SIMD multiplication unit,       this percentage would have been higher. So they reused some FP hardware to       keep the transistor count low. Furthermore, doing things this way allows       them to use the existing 64-bit data paths inside the CPU to do 128-bit       computation. Adding dedicated SIMD floating-point hardware and a 128-bit       internal data path to push vectors down would have really eaten up       transistor resources. Intel was also able to limit the changes to the       PIII's instruction decoder by implementing 128-bit SIMD FP in this manner.       Finally, the fact that the SIMD adder and multiplier are independent and       on two different ports, the PIII can dispatch a 64-bit add and a 64-bit       multiply at the same time.&lt;/p&gt;       &lt;p&gt;Remember that all of this       128-bit talk applies only to floating-point instructions. Old-school       integer MMX calculations are still restricted to the world of 64-bits.       Such is the price of backwards compatibility.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;h2&gt;Interrupts&lt;/h2&gt;       &lt;p&gt;By breaking up the       128-bit ops into two 64-bit uops ("uop" = microinstruction) and       running them either concurrently or sequentially, the PIII opens itself up       to the possibility that one of the uops will encounter a snag and have to       bail out ("throw an exception") after the other one has already       been retired.  If this were to happen, then only half of the 128-bit       destination register would hold a valid result.  Ooops.  &lt;/p&gt;       &lt;p&gt;To prevent this, the PIII       includes special hardware in the form of a Check Next Micro-Operation (CNU)       mechanism.  What this hardware does is keep the first uop from       retiring if the second one throws an exception. This means that once the       re-order buffer (he keeps track of execution and retirement) gets the       first, completed uop of a 128-bit instruction, it has to wait up for the       second uop to finish before it can retire them both.  This has the       potential to slow things down.&lt;/p&gt;       &lt;p&gt;Intel got around this by       taking advantage of a common case in multimedia processing.  Often,       as in the case of saturated arithmetic, exceptions like overflow and       underflow are &lt;b&gt;masked&lt;/b&gt;, which means that the programmer has told the       processor to just ignore them.  If an MMX or SSE instruction has its       interrupts masked, then since the PIII would ignore the exception anyway       it just doesn't bother having the re-order buffer (ROB) wait up for the       second uop.  In this case then, the ROB can go ahead and retire each       uop individually.  This is much faster, and since it's the common       case it reduces the impact of exception handling on performance. &lt;/p&gt;       &lt;h2&gt;3DNow! and Advanced       3DNow!&lt;/h2&gt;       &lt;p&gt;AMD's 3DNow!, as it's       implemented on the Athlon, faces problems similar to those faced by SSE.       Since 3DNow!, like SSE, incorporates MMX in all its 64-bit, x87       register-sharing glory, it has to deal with all the less desirable       features of MMX (only 64-bit integer computation, the two-operand       instruction format, etc.). 3DNow! takes the 57 MMX instructions and adds       to them 21 unique instructions that handle floating-point arithmetic, for       a total of 78 instructions. The Athlon's Advanced 3DNow! adds another 24       new, SSE-like instructions (for DSP, cache hinting, etc.), bringing the       SIMD instruction count up to 114.&lt;/p&gt;       &lt;p&gt;3DNow! simulates four-way       single precision (128-bit) FP computation the same way that the PIII does,       by breaking 4-way instructions down into a pair of 2-way       microinstructions, and executing them in parallel on two different SIMD       execution units. Like the PIII, the two units are independent of each       other, and one does addition and the other multiplication. This means that       for 3DNow! to be able to do sustained 128-bit computation, it has to       either issue a 2-way single precision multiply and a 2-way single       precision add in parallel. However, unlike either the PIII or Altivec,       3DNow has no 128-bit instructions. So any "128-bit SIMD       computation" that it does is purely the result of using two 64-bit       instructions in parallel. Another big difference between the Athlon's SIMD implementation and the       PIII's is that the Athlon has two, independent, fully-pipelined       floating-point functional units, and both of them do double duty as SIMD       FUs. (Recall that the PIII has two FPUs that aren't fully pipelined, and       only one of them does double duty as a SIMD FU.)&lt;/p&gt;       &lt;p&gt;The final important difference between SSE and 3DNow! is the fact that all the 3DNow! operations, bother integer and floating-point, share the same 8 registers with MMX and x87 operations. There are no added registers, like on the PIII. This is good and bad. It's good in that you can switch between 3DNow! and MMX instructions without a costly change of state. It's bad insofar as that's very few registers for the compiler to be working with. (The Athlon has a load of internal, microarchitectural 3DNow!/MMX/FP registers, so it can use register renaming to help alleviate some of the register starvation.  The PIII also has microarchitectural rename registers for this purpose, but the Athlon has more of them.)&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;MAJC&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;I want to touch very briefly       on Sun's upcoming MAJC architecture, because it handles SIMD in a       completely different way than any of the above CPUs. Sun didn't take an       existing CPU design and add SIMD capabilities to it in the form of a       dedicated SIMD unit. What they did instead was integrate SIMD support       seamlessly into the design of the processor itself. &lt;/p&gt;       &lt;p&gt; If your read my &lt;a href="http://arstechnica.com/articles/paedia/4q99/majc/majc-1.html"&gt;article       on Sun's MAJC&lt;/a&gt;, then you're familiar with the fact that it's a 4-wide       VLIW processor. The cool thing about MAJC is that all four of its       functional units are data-type agnostic. There are no integer units or       floating-point units. (More technically, there are no integer or fp &lt;i&gt;logical       pipes&lt;/i&gt;, but there is, in fact dedicated &lt;i&gt;hardware&lt;/i&gt; at the end of       each pipe.) Any FU can handle any type of data, which makes for       a number of interesting possibilities. (According to Sun's docs,       one of the FUs is an "extended subset" of the other three. So       they're not all totally identical, but nearly so.) One of the things you       can do with this is feed the same instruction stream to each FU, while       feeding four different data streams to each one to do       4-way, 128-bit SIMD integer or floating-point SIMD! &lt;/p&gt;       &lt;p&gt;  &lt;/p&gt;       &lt;div align="center"&gt;&lt;img src="http://media.arstechnica.com/cpu/4q99/majc/figure3.gif" border="0" height="375" width="428" /&gt;&lt;/div&gt;              &lt;p&gt;Sun has already stated       that this is how they'll do SIMD with MAJC.  I'll be interested to       see some more details on the types of instructions that they'll implement.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;h2&gt;Conclusions&lt;/h2&gt;       &lt;p&gt;There is &lt;i&gt;so&lt;/i&gt; much       more that can be said about these three SIMD implementations.  It       would be nice to be able to include a detailed breakdown/comparison of the       instructions each one offers, in order to get a more nuanced understanding       of the functionality each affords.  Also, I haven't even talked much       about instruction latencies or throughput for any of these architectures;       both of these factors greatly impact performance.  Finally, each       instruction set includes special instructions for manipulating the data       stream, manipulating the cache hierarchy, loading and storing vectors,       etc.  Including these factors in the discussion would almost double       the length of this article!  A follow-up that deals more       in-depth with these critical issues is in order.&lt;/p&gt;       &lt;p&gt;Nevertheless, this       overview has covered some of the basic SIMD concepts and implementation       issues relevant for current personal computing market. Also, as I said at       the outset, this article is meant to be read in conjunction with my &lt;a href="http://arstechnica.com/articles/paedia/cpu/g4vsk7/g4vsk7-1.html"&gt;previous       architectural comparison&lt;/a&gt;.  Right now, I think       it's clear that AltiVec's SIMD implementation is the cleanest, most       extensible, and most powerful of the current lot.  However, Intel is       including the sequel to SSE, SSE2, in Willamette, so we'll have to see       what kind of advancements it brings with it.  Also, while it might       not be immediately relevant for the PC market, Sony's Playstation2 makes       heavy use of 128-bit SIMD calculations.  When (or if) I get my hands       on some tech docs for that, I'll be sure to do a write-up on it.&lt;/p&gt;       &lt;p&gt; &lt;/p&gt;       &lt;h2&gt;Bibliography&lt;/h2&gt;       &lt;p&gt;I have to take a moment       to thank Walter NisticÚ for his help with this article. His feedback was       invaluable in helping me clarify some of the differences between the       implementations. I also want to thank Chris Rijk over at &lt;a href="http://aceshardware.com/"&gt;Ace's&lt;/a&gt;       for updating me on Sun's MAJC SIMD implementation. Now, on to the       bibliography...&lt;/p&gt;       &lt;ul&gt;&lt;li&gt;&lt;a href="http://developer.intel.com/technology/itj/q31997.htm"&gt;Intel           Technology Journal, Q3 1997 Issue&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://developer.intel.com/technology/itj/Q21999/ARTICLES/art_2.htm"&gt;Pentium           III Processor Implementation Tradeoffs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://developer.intel.com/technology/itj/Q21999/ARTICLES/art_1.htm"&gt;The           Internet Streaming SIMD Extensions&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://it3dnow.ngi.it/recensioni/SIMD_set_survey/"&gt;SIMD           Instruction Set Survey&lt;/a&gt;, Walter NisticÚ&lt;/li&gt;&lt;/ul&gt;       &lt;p&gt;The following white       papers are available from Motorola's website&lt;/p&gt;       &lt;ul&gt;&lt;li&gt;Motorola's Altivec           Technology, Sam Fuller&lt;/li&gt;&lt;li&gt;AltiVec Technology (PPC-C1-AltiVec-990920.pdf)&lt;/li&gt;&lt;/ul&gt;       &lt;p&gt;The following white       papers are available from AMD&lt;/p&gt;       &lt;ul&gt;&lt;li&gt;AMD Athlon Processor Technical Brief&lt;/li&gt;&lt;li&gt;AMD Extensions to the 3DNow! and MMX Instruction Sets Manual&lt;/li&gt;&lt;li&gt;3DNow! Technology Manual&lt;/li&gt;&lt;li&gt;AMD Athlon Processor Technical Brief&lt;/li&gt;&lt;/ul&gt;      &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-1941179587335832188?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/1941179587335832188/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=1941179587335832188' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/1941179587335832188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/1941179587335832188'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/05/simd-architectures.html' title='SIMD architectures'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-2450217002693528199</id><published>2008-05-09T08:11:00.000-07:00</published><updated>2008-05-09T08:17:10.092-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/計算機/Playstation2'/><title type='text'>The PlayStation2 vs. the PC: a system-level comparison of two 3D platforms</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;    By &lt;/span&gt;&lt;a style="font-family: courier new;" href="http://arstechnica.com/authors.ars/hannibal"&gt;Jon Stokes&lt;/a&gt;&lt;span style="font-family: courier new;"&gt; |     Published: April 15, 2000 - 10:00PM CT&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2 style="font-family: courier new;"&gt;Introduction &lt;/h2&gt;      &lt;div style="font-family: courier new;" class="Body"&gt;      &lt;p&gt;When I was in the research phase for my recent &lt;a href="http://www.arstechnica.com/reviews/1q00/playstation2/ee-1.html"&gt;technical article on the Emotion Engine&lt;/a&gt;, I thought for a while there that I was never going to figure out how the PS2 worked. The PS2 is such a bizarre and powerful beast that it took me many hours of poring over articles and slide presentations just to get my bearings with it. Well, it seems I'm not alone in my struggle to understand the capabilities and limitations of one of the most painfully innovative pieces of hardware to hit the consumer market in quite a long time. I got some good feedback from PS2 developers who are also having a hard time with the new hardware. In fact, to get an idea of just how bad the situation is, check out &lt;a href="http://www.msnbc.com/news/397313.asp"&gt;this article&lt;/a&gt; on MSNBC, which discusses the difficulties that even the most experienced of console programmers are having in learning how to code for the PS2. When the programmers responsible for some of the greatest console games ever made say that the PS2's learning curve is steep, you know something's up.&lt;/p&gt; &lt;p&gt;In this article, I want to try and get a handle on some of the aspects of the PS2 that make it so fundamentally different from the current crop of PCs, and in the process shed some light on the difficulties developers will face in going from the PC to the PS2. Specifically, I'll look at the overall designs of the PS2 and PC, and explain how the demands of dynamic media processing have caused the design of the PS2 architecture to differ from the PC's to the point where developers will have to rethink how they move code and data around to render a 3D environment.&lt;/p&gt; &lt;h3&gt;New wine and old bottles: Dynamic media vs. static applications&lt;/h3&gt; &lt;p&gt;To kick off the discussion, I'm going to use a very prescient article published in 1996 by Keith Diefendorff and Pradeep K. Dubey entitled, "How Multimedia Workloads Will Change Processor Design." In this article, Diefendorff and Dubey argue that the processing of dynamic media will result in fundamental changes in processor design, and they detail what some of those changes will look like. In parts, it sounds as if they're looking ahead into the future and describing the PS2. Since this article describes the current situation so well, I'll be drawing on it to frame the discussion.&lt;/p&gt; &lt;p&gt;Diefendorff et al. start out by distinguishing media applications from more traditional applications by noting that media apps are examples of what they call dynamic processing. What this basically means is that the instruction stream doesn't really change all that fast, but the data stream changes constantly. Or, put more concretely, programs like 3D games and scientific applications deal with very large amounts of data, but the groups of instructions that operate on these large data chunks are usually very small. The most common situation is where you have a small loop that iterates through a large matrix or series of matrices many, many times.&lt;/p&gt; &lt;p&gt;Contrast this to a more traditional, static processing application like a word processor, which uses many different segments of code (menus, wizards, spell checkers, etc.) to operate on a single data file (the document). In this type of application, the data stream is pretty stagnant, and doesn't change very much. The instruction stream, however, is all over the map. One minute you're firing up the spell checker to process the file, the next minute you're changing the fonts, and then when that's done, maybe you export it to a different format like Postscript or HTML.&lt;/p&gt; &lt;p&gt;The PC was designed with just such spreadsheets, word processors and other static processing applications in mind. Within recent years, however, it has undergone some significant changes, particularly with the addition of special-purpose hardware like 3D accelerators and sound processors. Such added hardware, however, represents an attempt to put new wine in an old bottle. At some point, Diefendorff and Dubey predict, all media processing functionality will be integrated on a single die, and specialized DSP processing hardware will become obsolete. Furthermore, such designs will feature extremely wide data paths between the on-die components. Enter the PS2...&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Caching, Bandwidth, and 3D rendering&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;This change in the nature of the  instruction and data streams has significant implications for system design. One  of the first things to be affected is the cache. Consider the following  illustration of caching for a static application.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://arstechnica.com/cpu/2q00/ps2/figure3.gif" border="0" height="312" width="472" /&gt;&lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;In the above diagram, you'll notice that there's a steady flow of instructions through the instruction cache, resulting in a high turnover rate. Instructions don't stay in the cache long before getting booted out by the next instruction that the machine needs. The data cache, on the other hand, can collect up the most commonly used pieces of data and just hold onto them while all those instructions in the instruction stream process them. You can just drop a whole piece of data in there, like a spreadsheet or a document, and leave it there while you run a steady stream of instructions over it to modify it. In such a situation, we say that the data exhibits high &lt;b&gt;locality of reference&lt;/b&gt;, whereas the instructions exhibit lower locality of reference. &lt;/p&gt; &lt;p&gt;In contrast, a dynamic media app has the opposite cache usage behavior. And in fact, the problem is exacerbated by the fact that a media app pushes data through the data cache much faster than a static app pushes code through the instruction cache. &lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://arstechnica.com/cpu/2q00/ps2/figure4.gif" border="0" height="312" width="472" /&gt;&lt;/p&gt; &lt;p&gt;So while static apps can sometimes make poor use of the instruction cache, media apps almost always make extremely poor use of the data cache. There's just too much data to be processed in too short of an amount of time to be sticking it in a cache and leaving it there. The cache acts as more of a brief stopping-off point for data than as a real cache. However, media apps have excellent locality of reference when it comes to instructions. Most of that data that moves through the cache is processed by loops and other very small bits of code, which are often small enough to fit in the instruction cache and stay there. So the instructions just hang out in the cache and monotonously grind away at all that data that's flying by them.&lt;/p&gt; &lt;p&gt;The other, major difference between  static apps and dynamic apps are their bandwidth needs. Since a static app can  drop all its instructions and data into a cache without worrying too much about  needing to fetch some more anytime soon, systems designed for such applications  feature large caches connected by relatively low bandwidth pipes. Dynamic apps,  on the other hand, can make do with smaller caches, but since they transfer so  much data they need much more bandwidth between them.&lt;/p&gt; &lt;p&gt;Here's a goofy example to help you  visualize what I'm talking about: imagine a series of large buckets, connected  by pipes to a main tank, with a cow lapping water out of each bucket. Since cows  don't drink too fast, the pipes don't have to be too large to keep the buckets  full and the cows happy. Now imagine that same setup, except with elephants on  the other end instead of cows. The elephants are sucking water out so fast that  you've got to do something drastic to keep them happy. One option would be to  enlarge the pipes just a little (*cough* AGP *cough*), and stick insanely large  buckets on the ends of them (*cough* 64MB GeForce *cough*). You then fill the  buckets up to the top every morning, leave the water on all day, and pray to God  that the elephants don't get too thirsty. This only works to a certain extent  though, because a really thirsty elephant would still end up draining the bucket  faster than you can fill it. And what happens when the elephants have kids, and  the kids are even thirstier? You're only delaying the inevitable with this  solution, because the problem isn't with the buckets, it's with the pipes  (assuming an infinite supply of water). A better approach would be to just ditch  the buckets altogether and make the pipes really, really large. You'd also want  to stick some pans on the ends of the pipes as a place to collect the water  before it gets consumed, but the pans don't have to be that big because the  water isn't staying in them very long.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;3D and caching on the PC&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;The above analogy, silly though it seems, sums up one of the primary differences between the design of the PS2 and that of a PC. 3D games are just the sort of dynamic media apps that the PC wasn't designed to cope with--they're the elephants in the analogy. PC game programmers operate in a world of small pipes and large buckets, and they design games to fit that paradigm. Let's take a look at the architecture of the PC, particularly the caches and connections between them, from a 3D programmer's perspective.&lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://arstechnica.com/cpu/2q00/ps2/figure1.gif" border="0" height="550" width="402" /&gt;&lt;/div&gt; &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;Note that I didn't include the caches on the accelerator's core itself; I only included the VRAM. I did this for a number of reasons. First and foremost, it doesn't really impact our discussion much--you'll see why once we get to the PS2. Second, detailed information on the innards of most 3D chips is kind of hard to come by. Finally, this article is trying to give a more general overview, without getting into to much detail. So just assume that there's cache hanging around inside the accelerator that I'm ignoring.&lt;/p&gt; &lt;p&gt;Let's now go step-by-step through the process of producing a couple of frames of 3D on the above, non-hardware T&amp;amp;L PC system. We'll assume that the application code and the data all fit in main memory. &lt;/p&gt; &lt;h3&gt;Geometry Stage&lt;/h3&gt; &lt;p&gt;The first stage of the process is called the geometry stage. This is where a description of the object and its position in the 3D world are created. This description, called a &lt;b&gt;display list&lt;/b&gt;, is a sequence of commands, parameters, and other data that can be further processed by the next stage. In order to create the display list, the CPU has to first get the 3D engine code and the data out of main memory and load it into the L1 and L2 caches to be worked on. So the L1 and L2 caches act as sort of a workspace where the CPU can keep code and data in order to do tessellation, setup, transformation, and lighting. These display lists eventually get written back out to main memory before going on to the next stage. In the &lt;b&gt;geometry stage&lt;/b&gt;, the FSB and the main memory bus see the most traffic, because all that data is being shuffled back and forth between the CPU caches and RAM.&lt;/p&gt; &lt;div align="center"&gt;&lt;br /&gt;&lt;img src="http://arstechnica.com/cpu/2q00/ps2/figure5.gif" border="0" height="330" width="241" /&gt;&lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;h3&gt;Rendering Stage&lt;/h3&gt; &lt;p&gt;While the geometry stage is producing one frame, the rendering stage is producing the bitmap of the next frame. This bitmap is a 2D, pixel-by-pixel representation of the 3D scene, which will eventually be drawn on the screen as a frame. The actual rendering of the 2D bitmap from the 3D scene is handled by the video card, so this means that the display lists produced by the CPU have to make their way out of main memory, across the AGP bus, and into the video card's video memory. Here, the vid card builds the bitmaps in the frame buffers by executing the display lists. The display lists tell the vid card to draw triangles and lines, do coloring and shading, apply texture maps, etc. The application of texture maps means moving the textures out of main memory and into the video memory, which even further stresses the AGP and main memory buses.&lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://arstechnica.com/cpu/2q00/ps2/figure6.gif" border="0" height="330" width="241" /&gt;&lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;h3&gt;Display Stage&lt;/h3&gt; &lt;p&gt;Finally, in the display stage, the next frame is being painted onto the screen. This painting involves fetching data from the frame buffer and converting that digital pixel data into a stream of analog signals that the monitor can understand. This stage makes heavy use of the video memory and the video memory bus.&lt;/p&gt; &lt;div align="center"&gt;&lt;br /&gt;&lt;img src="http://arstechnica.com/cpu/2q00/ps2/figure7.gif" border="0" height="330" width="241" /&gt;&lt;/div&gt; &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;You should be able to tell from the above, very general description just how closely the 3D rendering process is fitted to the PC's architecture. To further nuance the description, let's look at the overall division of labor for the rendering process on a standard PC. First up, here's a table that gives you a very general idea of how much cache is available to the rendering pipeline.&lt;/p&gt; &lt;div align="center"&gt;   &lt;center&gt;   &lt;table border="1" bordercolor="#008000" width="73%"&gt;     &lt;tbody&gt;       &lt;tr&gt;         &lt;td width="63%"&gt;&lt;b&gt;Pentium III, 32MB TNT2 Ultra&lt;/b&gt;&lt;/td&gt;         &lt;td width="37%"&gt; &lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="63%"&gt;L1 cache (instruction, data)&lt;/td&gt;         &lt;td width="37%"&gt;16K 4-way, 16K 4-way&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="63%"&gt;L2 cache&lt;/td&gt;         &lt;td width="37%"&gt;256K unified&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="63%"&gt;Video Memory&lt;/td&gt;         &lt;td width="37%"&gt;32MB&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="63%"&gt;&lt;b&gt;Total&lt;/b&gt;&lt;/td&gt;         &lt;td width="37%"&gt;33,056K&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;   &lt;/table&gt;   &lt;/center&gt; &lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Now let's see how that cache is divided up geographically and functionally.&lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://arstechnica.com/cpu/2q00/ps2/figure8.gif" border="0" height="550" width="402" /&gt;&lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;As we'll soon see, the above division of labor doesn't quite work for the PS2. In fact, that's a major understatement, so let me rephrase: it doesn't work at all. The PS2 requires you to rethink how you divide up the labor between the stages of the rendering pipeline, and how you move code and data around between those stages.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Caching on the PS2&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;First, let's take a look at the PS2's bus and cache layout.&lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://arstechnica.com/cpu/2q00/ps2/figure2.gif" border="0" height="564" width="466" /&gt;&lt;/div&gt; &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;What I've tried to represent in the above figure is that the caches are much smaller than those on the PC, but the buses connecting them are much wider. Again, I'm sure that if I had access to the details of the Graphics Synth's architecture, I'd almost certainly find that it has cache inside of it, too, in various places.&lt;/p&gt; &lt;p&gt;In place of the PC's north bridge, the PS2 has a 10-channel &lt;b&gt;Direct Memory Access Controller (DMAC)&lt;/b&gt; that coordinates data transfers between the units and caches on the Emotion Engine's 128-bit and 64-bit internal data paths. The PS2 also uses two, 128MB RDRAM banks for its main memory, each of which is connected to the EE's on-die DMAC by a high-speed 16-bit bus. RDRAM has the virtue of being an extremely high-bandwidth memory solution, so it can keep that 10-channel DMAC (which can manage 10 simultaneous bus transfers) busy and those internal caches fed.&lt;/p&gt; &lt;p&gt;Speaking of the PS2's internal caches, let's look at their sizes, and how they stack up to a PIII's caches, especially with respect to the first few stages of the rendering pipeline.&lt;/p&gt; &lt;div align="center"&gt;   &lt;center&gt;   &lt;table border="1" bordercolor="#008000" width="73%"&gt;     &lt;tbody&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;Playstation2&lt;/b&gt;&lt;/td&gt;         &lt;td width="50%"&gt; &lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;L1 cache&lt;br /&gt;          (instruction,data)&lt;/td&gt;         &lt;td width="50%"&gt;16K 2-way instruction, 8K 2-way data&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;SPRAM&lt;/td&gt;         &lt;td width="50%"&gt;16K&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;VU0 cache&lt;br /&gt;          (instruction + data)&lt;/td&gt;         &lt;td width="50%"&gt;16K + 16K = 32K&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;VU1 cache&lt;br /&gt;          (instruction + data)&lt;/td&gt;         &lt;td width="50%"&gt;16K + 16K = 32K&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;Video memory&lt;/td&gt;         &lt;td width="50%"&gt;4MB&lt;/td&gt;       &lt;/tr&gt;       &lt;tr&gt;         &lt;td width="50%"&gt;&lt;b&gt;Total&lt;/b&gt;&lt;/td&gt;         &lt;td width="50%"&gt;4,200K&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;   &lt;/table&gt;   &lt;/center&gt; &lt;/div&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;As you can tell from the above chart, the PIII system outlined earlier has almost &lt;b&gt;8 times&lt;/b&gt; the amount of cache in its rendering pipeline than the PS2 does. Even if we take the video memory and the cache on the accelerator card completely out of the equation, the PC still has about 3 times the cache of the PS2. Furthermore, what little cache the PS2 has is divided up among a larger number of small caches. Remember the zoo analogy: large buckets and small pipes vs. small pans and large pipes.&lt;/p&gt; &lt;p&gt;The PS2's approach is causing developers to rethink how they move data inside the machine. In a comment in the &lt;a href="http://slashdot.org/"&gt;/.&lt;/a&gt; thread about my PS2 article, one ex-PS2 developer noted that the VU caches are too small to store a whole model or 32-bit texture, so programmers were pulling their hair out trying to figure out how to deal with the size limitation. He pointed out that one group that had had PS2 development units for a while took the strategy of constantly downloading textures and models into the VU and processors, instead of downloading them once, caching them, and working on them inside the cache. This approach was running the 10-channel DMAC at 90% capacity! This kind of aggressive use of bandwidth resources is exactly the kind of thing PS2 developers will have to do. Between the RAMBUS memory banks, the 10-channel DMAC and the 128-bit internal data bus, the PS2 has bandwidth to burn--what it doesn't have is internal cache. Currently, developers are thinking in terms of 3D cards with large on-board memory that can cache large models and textures, and modestly sized L1 and L2 caches for storing code and data.&lt;/p&gt; &lt;p&gt;The PS2 is the exact opposite, though. There's memory-to-processor bandwidth out the wazoo. The RIMMS are the cache, and the available bandwidth is such that you can get away with storing everything there and downloading it on the fly. So with the PS2, code and data have to be constantly streamed over the wide internal buses in order arrive at the functional units right when they're needed. Of course, then the trick is scheduling the memory transfers so that you always have what you need on hand and latency doesn't kill you. I'm not so sure how developers will tackle this, but it'll be interesting to see what techniques they'll use. I'm sure the PS2 has some sophisticated prefetching hardware that's not discussed in any of the documentation I have.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;SIMD on the PS2 and conclusions&lt;/h2&gt;      &lt;div class="Body"&gt;      &lt;p&gt;Diefendorff and Dubey point out one more important way that dynamic media processing will affect system design. They note:&lt;/p&gt; &lt;blockquote&gt;   &lt;p&gt;&lt;span style="color:#ff8000;"&gt;"Input data streams are frequently large   collections of small data elements such as pixels, vertices, or   frequency/amplitude values. The parallelism in these streams is fine grained.   And because elements of these large input data streams tend to undergo   identical processing (filtering, transformations, and so on), it lends itself   to machines with SIMD hardware units operating in parallelÖfor media   processing, simple SIMD execution units with wide data paths would be able to   achieve significant speedups without this enormous complexity." (p.2)&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;What they're saying is that media applications exhibit a very high degree of &lt;b&gt;data parallelism&lt;/b&gt;, much more so than static apps. Static applications, on the other hand, exhibit varying degrees of &lt;b&gt;instruction-level parallelism&lt;/b&gt;, but little data parallelism. Here's a diagram that shows a static application at work.&lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://www.arstechnica.com/cpu/2q00/ps2/figure9.gif" border="0" height="272" width="392" /&gt;&lt;/div&gt; &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;In contrast, dynamic media processing exhibits very little instruction-level parallelism and massive amounts of data parallelism. What instruction stream parallelism a dynamic app does have usually happens at the thread level, and not at the individual instruction level. As a result, such apps lend themselves to &lt;a href="http://www.arstechnica.com/cpu/1q00/simd/simd-1.html"&gt;SIMD processing&lt;/a&gt;. &lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://www.arstechnica.com/cpu/2q00/ps2/figure10.gif" border="0" height="312" width="318" /&gt;&lt;/div&gt; &lt;div align="center"&gt; &lt;/div&gt; &lt;p&gt;The PS2 has two dedicated 128-bit SIMD floating-point vector units, VU0 and VU1, each of which are able to process massive amounts of data per clock cycle. In addition, the MIPS III CPU core on the Emotion Engine can do 128-bit integer SIMD by locking together its two 64-bit integer pipes. So the PS2 fits the profile of having multiple parallel SIMD units connected by high-bandwidth pipes.&lt;/p&gt; &lt;p&gt;Again, the issue is how to make use of these resources. PC programmers aren't used to having access to that kind of raw, data processing power. In fact, from what I've heard, very few developers are using both vector units.&lt;/p&gt; &lt;p&gt;We're beginning to see vector processing take off on the PC, and I have no doubt that it will be very prevalent in the next few years. However, until the PC is able to overcome its bandwidth bottlenecks it won't be able to keep its SIMD units fed as well as the PS2. &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;h3&gt;Conclusions&lt;/h3&gt; &lt;p&gt;So which machine is more powerful? Well, if you're talking 3D gaming and you mean right now, I wouldn't hesitate to give the crown to the PS2. Looking ahead to the next two or three years, the future looks much less certain. It'll be quite a while before developers are able to figure out how to harness the full capabilities of the PS2, and while they're scratching their heads the PC will be getting more and more powerful. As we'll soon see with the NV15, the PC is still advancing quickly under the old "large buckets and slightly bigger pipes" paradigm. However, the PS2 represents the true next generation of media processing, and until the PC catches up with it in terms of bandwidth and overall data throughput (read "SIMD") it can't be worthily called a true dynamic media machine. That being said, a look at the PS2 is a look into the (probably near) future of the PC. The data pipes will indeed get wider, SIMD will increase the amount of media data a PC can process, and the PC will resemble more and more the kind of media machine that Diefendorff and Duby described, and that the engineers at Sony and Mitsubishi built.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;h3&gt;Bibliography&lt;/h3&gt; &lt;ul&gt;&lt;li&gt;Keith Diefendorff and Pradeep K. Dubey, "How Multimedia Workloads     Will Change Processor Design." Computer, September 1997   &lt;/li&gt;&lt;li&gt;Stephen P. VanderWiel and David J. Lija. "When Caches Aren't Enough:     Data Prefetching Techniques." &lt;i&gt;Computer&lt;/i&gt;   &lt;/li&gt;&lt;li&gt;Bruce Shriver, Bennett Smith. &lt;i&gt;The Anatomy of a High-Performance     Microprocessor: A Systems Perspective&lt;/i&gt;. Los Alamitos, CA: IEEE Computing     Society Press, 1998   &lt;/li&gt;&lt;li&gt;&lt;a href="http://arstechnica.com/reviews/1q00/playstation2/ee-1.html"&gt;Sound     and Vision: A Technical Overview of the Emotion Engine&lt;/a&gt;, Jon Stokes.&lt;/li&gt;&lt;/ul&gt;      &lt;/div&gt;&lt;/div&gt;      &lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-2450217002693528199?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/2450217002693528199/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=2450217002693528199' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/2450217002693528199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/2450217002693528199'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/05/playstation2-vs-pc-system-level.html' title='The PlayStation2 vs. the PC: a system-level comparison of two 3D platforms'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-649545711280722790</id><published>2008-04-30T01:37:00.000-07:00</published><updated>2008-04-30T01:38:15.668-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章'/><title type='text'>AES/EBU From Wikipedia, the free encyclopedia</title><content type='html'>&lt;!-- start content --&gt;    &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;The digital audio standard frequently called &lt;b&gt;AES/EBU&lt;/b&gt;, officially known as &lt;b&gt;AES3&lt;/b&gt;, is used for carrying &lt;a href="http://en.wikipedia.org/wiki/Digital_audio" title="Digital audio"&gt;digital audio&lt;/a&gt; signals between various devices. It was developed by the &lt;a href="http://en.wikipedia.org/wiki/Audio_Engineering_Society" title="Audio Engineering Society"&gt;Audio Engineering Society&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/European_Broadcasting_Union" title="European Broadcasting Union"&gt;European Broadcasting Union&lt;/a&gt; (EBU) and first published in 1985, later revised in 1992 and 2003. Both AES and EBU versions of the standard exist. Several different physical connectors are also defined as part of the overall group of standards. A related system, &lt;a href="http://en.wikipedia.org/wiki/S/PDIF" title="S/PDIF"&gt;S/PDIF&lt;/a&gt;, was developed essentially as a consumer version of AES/EBU, using connectors more commonly found in the consumer market.&lt;/span&gt; (AES) and the &lt;/p&gt; &lt;table style="font-family: courier new;" id="toc" class="toc" summary="Contents"&gt; &lt;tbody&gt;&lt;tr&gt; &lt;td&gt; &lt;div id="toctitle"&gt; &lt;h2&gt;&lt;span style="font-size:85%;"&gt;Contents&lt;/span&gt;&lt;/h2&gt;  &lt;span class="toctoggle"  style="font-size:85%;"&gt;[&lt;a href="javascript:toggleToc()" class="internal" id="togglelink"&gt;hide&lt;/a&gt;]&lt;/span&gt;&lt;/div&gt; &lt;ul&gt;&lt;li class="toclevel-1"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#Hardware_connections"&gt;&lt;span class="tocnumber"&gt;1&lt;/span&gt; &lt;span class="toctext"&gt;Hardware connections&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="toclevel-1"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#The_Protocol"&gt;&lt;span class="tocnumber"&gt;2&lt;/span&gt; &lt;span class="toctext"&gt;The Protocol&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; &lt;ul&gt;&lt;li class="toclevel-2"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#Time_slots_0_to_3"&gt;&lt;span class="tocnumber"&gt;2.1&lt;/span&gt; &lt;span class="toctext"&gt;Time slots 0 to 3&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="toclevel-2"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#Time_slots_4_to_7"&gt;&lt;span class="tocnumber"&gt;2.2&lt;/span&gt; &lt;span class="toctext"&gt;Time slots 4 to 7&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="toclevel-2"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#Time_slots_8_to_27"&gt;&lt;span class="tocnumber"&gt;2.3&lt;/span&gt; &lt;span class="toctext"&gt;Time slots 8 to 27&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="toclevel-2"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#Time_slots_28_to_31"&gt;&lt;span class="tocnumber"&gt;2.4&lt;/span&gt; &lt;span class="toctext"&gt;Time slots 28 to 31&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="toclevel-2"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#The_Channel_Status_Bit_in_AES.2FEBU"&gt;&lt;span class="tocnumber"&gt;2.5&lt;/span&gt; &lt;span class="toctext"&gt;The Channel Status Bit in AES/EBU&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/li&gt;&lt;li class="toclevel-1"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#See_also"&gt;&lt;span class="tocnumber"&gt;3&lt;/span&gt; &lt;span class="toctext"&gt;See also&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="toclevel-1"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#References"&gt;&lt;span class="tocnumber"&gt;4&lt;/span&gt; &lt;span class="toctext"&gt;References&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="toclevel-1"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES/EBU#External_links"&gt;&lt;span class="tocnumber"&gt;5&lt;/span&gt; &lt;span class="toctext"&gt;External links&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;script type="text/javascript"&gt; //&lt;![CDATA[  if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); }  //]]&gt; &lt;/script&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="Hardware_connections" id="Hardware_connections"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h2 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=1" title="Edit section: Hardware connections"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;Hardware connections&lt;/span&gt;&lt;/h2&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;The AES3 standard parallels part 4 of the international standard &lt;a href="http://en.wikipedia.org/wiki/International_Electrotechnical_Commission" title="International Electrotechnical Commission"&gt;IEC&lt;/a&gt;&lt;/span&gt; 60958. Of the physical interconnection types defined by IEC 60958, three are in common use:&lt;/p&gt; &lt;ul style="font-family: courier new;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;IEC 60958 Type I &lt;a href="http://en.wikipedia.org/wiki/Balanced_line" title="Balanced line"&gt;Balanced&lt;/a&gt; – 3-conductor, 110-&lt;a href="http://en.wikipedia.org/wiki/Ohm_%28unit%29" class="mw-redirect" title="Ohm (unit)"&gt;ohm&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Twisted_pair" title="Twisted pair"&gt;twisted pair&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/XLR" class="mw-redirect" title="XLR"&gt;XLR&lt;/a&gt; connector, used in professional installations (AES3 standard)&lt;/span&gt; cabling with an &lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;IEC 60958 Type II &lt;a href="http://en.wikipedia.org/wiki/Balanced_line" title="Balanced line"&gt;Unbalanced&lt;/a&gt; – 2-conductor, 75-ohm &lt;a href="http://en.wikipedia.org/wiki/Coaxial_cable" title="Coaxial cable"&gt;coaxial cable&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/RCA_connector" title="RCA connector"&gt;RCA connector&lt;/a&gt;, used in consumer audio&lt;/span&gt; with an &lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;IEC 60958 Type II Optical – &lt;a href="http://en.wikipedia.org/wiki/Optical_fiber" title="Optical fiber"&gt;optical fiber&lt;/a&gt;, usually &lt;a href="http://en.wikipedia.org/wiki/Plastic" title="Plastic"&gt;plastic&lt;/a&gt; but occasionally glass, with an &lt;a href="http://en.wikipedia.org/wiki/F05_connector" class="mw-redirect" title="F05 connector"&gt;F05 connector&lt;/a&gt;, also used in consumer audio&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;The AES-3id standard defines a 75-ohm &lt;a href="http://en.wikipedia.org/wiki/BNC_connector" title="BNC connector"&gt;BNC&lt;/a&gt; electrical variant of AES3. More recently, professional equipment (notably by &lt;a href="http://en.wikipedia.org/wiki/Sony" title="Sony"&gt;Sony&lt;/a&gt;) has used this physical interconnection type. This uses the same cabling, patching and infrastructure as analogue or digital video, and is thus common in the broadcast industry.&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;F05 connectors, 5mm connectors for plastic &lt;a href="http://en.wikipedia.org/wiki/Optical_fiber" title="Optical fiber"&gt;optical fiber&lt;/a&gt;, are more commonly known by their &lt;a href="http://en.wikipedia.org/wiki/Toshiba" title="Toshiba"&gt;Toshiba&lt;/a&gt; brand name, &lt;a href="http://en.wikipedia.org/wiki/TOSLINK" title="TOSLINK"&gt;TOSLINK&lt;/a&gt;. The precursor of the IEC 60958 Type II specification was the Sony/Philips Digital Interface, or &lt;a href="http://en.wikipedia.org/wiki/S/PDIF" title="S/PDIF"&gt;S/PDIF&lt;/a&gt;. For details on the format of AES/EBU data, see the article on S/PDIF. Note that the electrical levels differ between AES/EBU and S/PDIF.&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;For information on the synchronization of digital audio structures, see the &lt;a href="http://en.wikipedia.org/wiki/AES11" title="AES11"&gt;AES11&lt;/a&gt; standard. The ability to insert unique identifiers into an AES3 bit stream is covered by the &lt;a href="http://en.wikipedia.org/wiki/AES52" title="AES52"&gt;AES52&lt;/a&gt; standard.&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;Other AES3 transport structures.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;AES3 digital audio format can also be carried over an &lt;a href="http://en.wikipedia.org/wiki/Asynchronous_Transfer_Mode" title="Asynchronous Transfer Mode"&gt;Asynchronous Transfer Mode&lt;/a&gt; network. The standard for packing AES3 frames into ATM cells is &lt;a href="http://en.wikipedia.org/wiki/AES47" title="AES47"&gt;AES47&lt;/a&gt;, and is also published as &lt;a href="http://en.wikipedia.org/wiki/IEC_62365" title="IEC 62365"&gt;IEC 62365&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="The_Protocol" id="The_Protocol"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h2 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=2" title="Edit section: The Protocol"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;The Protocol&lt;/span&gt;&lt;/h2&gt; &lt;div style="font-family: courier new;" class="thumb tright"&gt; &lt;div class="thumbinner" style="width: 302px;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Image:SPDIF_AES_EBU_protocol_colored.svg" class="image" title="Simple representation of the protocol for both AES/EBU and S/PDIF"&gt;&lt;img alt="Simple representation of the protocol for both AES/EBU and S/PDIF" src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/SPDIF_AES_EBU_protocol_colored.svg/300px-SPDIF_AES_EBU_protocol_colored.svg.png" class="thumbimage" border="0" height="301" width="300" /&gt;&lt;/a&gt;&lt;/span&gt; &lt;div class="thumbcaption"&gt; &lt;div class="magnify"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Image:SPDIF_AES_EBU_protocol_colored.svg" class="internal" title="Enlarge"&gt;&lt;img src="http://en.wikipedia.org/skins-1.5/common/images/magnify-clip.png" alt="" height="11" width="15" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt; Simple representation of the protocol for both AES/EBU and S/PDIF&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;The low-level protocol for data transmission in AES/EBU and S/PDIF is largely identical, and the following discussion applies for S/PDIF as well unless otherwise noted.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;AES/EBU was designed primarily to support &lt;a href="http://en.wikipedia.org/wiki/Pulse-code_modulation" title="Pulse-code modulation"&gt;PCM&lt;/a&gt; encoded audio in either &lt;a href="http://en.wikipedia.org/wiki/Digital_audio_tape" class="mw-redirect" title="Digital audio tape"&gt;DAT&lt;/a&gt; format at 48 kHz or &lt;a href="http://en.wikipedia.org/wiki/Compact_disk" class="mw-redirect" title="Compact disk"&gt;CD&lt;/a&gt; format at 44.1 kHz. No attempt was made to use a carrier able to support both rates, instead AES/EBU allows the data to be run at &lt;i&gt;any&lt;/i&gt; rate, and recovers the clock rate by encoding the data use &lt;a href="http://en.wikipedia.org/wiki/Biphase_mark_code" title="Biphase mark code"&gt;Biphase mark code&lt;/a&gt; (BMC).&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;The bit stream consists of the PCM audio data broken down into small samples and inserted into a larger structure that also carries various status and information data. The highest level organization is the &lt;b&gt;audio block&lt;/b&gt;, which roughly corresponds to a number of samples of the PCM data. Each block is broken into 192 &lt;b&gt;frames&lt;/b&gt; numbered 0 to 191. Each frame is further divided in 2 subframes (or channels): A (left) and B (right). Each subframe contains the information for one single &lt;a href="http://en.wikipedia.org/wiki/Sample_%28signal%29" class="mw-redirect" title="Sample (signal)"&gt;sample&lt;/a&gt; of the &lt;a href="http://en.wikipedia.org/wiki/PCM" class="mw-redirect" title="PCM"&gt;PCM&lt;/a&gt; audio, or more simply, one channel of audio. Each subframe is organized into 32 &lt;b&gt;time slots&lt;/b&gt; numbered 0 to 31, each of which corresponds roughly to a single bit. Not all of the time blocks send actual audio data, a number of them are set aside for signaling use, and others for transmitting data about the channels. In normal use only 20 time blocks are used for audio, providing a 20-bit sound quality (compare with a CD at 16 bits per sample). So a complete audio block basically contains 192 samples from two channels of audio and other data, containing 12288 bits in total.&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;The 32 bits of the time slots are used as following:&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="Time_slots_0_to_3" id="Time_slots_0_to_3"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h4 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=3" title="Edit section: Time slots 0 to 3"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;Time slots 0 to 3&lt;/span&gt;&lt;/h4&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;They do not actually carry any data but they facilitate clock recovery and subframe identification. They are not BMC encoded so they are unique in the data stream and they are easier to recognize, but they don't represent real bits. Their structure minimizes the &lt;a href="http://en.wikipedia.org/wiki/Direct_current" title="Direct current"&gt;DC&lt;/a&gt;&lt;/span&gt; component on the transmission line. Three preambles are possible :&lt;/p&gt; &lt;ul style="font-family: courier new;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;X (or M) : 11100010 if previous time slot was "0", 00011101 if it was "1". Marks a word for channel A (left) that isn't at the start of the data block.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Y (or W) : 11100100 if previous time slot was "0", 00011011 if it was "1". Marks a word that isn't for channel A (eg a word for channel B (right) in a stereo signal).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Z (or B) : 11101000 if previous time slot was "0", 00010111 if it was "1". Marks a word for channel A (left) at the start of the data block.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;They are called X, Y, Z from AES standard; M, W,B from the IEC 958 (an AES extension).&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;The 8-bit preambles are transmitted in the same time allocated to four time slots at the start of each sub-frame (time slots 0 to 3).&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="Time_slots_4_to_7" id="Time_slots_4_to_7"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h4 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=4" title="Edit section: Time slots 4 to 7"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;Time slots 4 to 7&lt;/span&gt;&lt;/h4&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;These time slots can carry auxiliary information such as a low-quality auxiliary audio channel for producer talkback or studio-to-studio communication. Alternately, they can be used to enlarge the audio word-length to 24 bits, although the devices at either end of the link must be able to use this non-standard format.&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="Time_slots_8_to_27" id="Time_slots_8_to_27"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h4 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=5" title="Edit section: Time slots 8 to 27"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;Time slots 8 to 27&lt;/span&gt;&lt;/h4&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;These time slots carry 20 bits of audio information starting with &lt;a href="http://en.wikipedia.org/wiki/LSB" title="LSB"&gt;LSB&lt;/a&gt; and ending with &lt;a href="http://en.wikipedia.org/wiki/Most_significant_bit" title="Most significant bit"&gt;MSB&lt;/a&gt;. If the source provides fewer than 20 bits, the unused LSBs will be set to the logical "0" (for example, for the 16-bit audio read from CDs bits 8-11 are set to 0).&lt;/span&gt;&lt;/p&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="Time_slots_28_to_31" id="Time_slots_28_to_31"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h4 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=6" title="Edit section: Time slots 28 to 31"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;Time slots 28 to 31&lt;/span&gt;&lt;/h4&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;These time slots carry associated bits as follows:&lt;/span&gt;&lt;/p&gt; &lt;ul style="font-family: courier new;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;V (28) Validity bit: it is set to zero if the audio sample word data are correct and suitable for D/A conversion. Otherwise, the receiving equipment may be instructed to mute its output during the presence of defective samples. It is used by most CD players to indicate that concealment rather than error correction is taking place.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;U (29) User bit: any kind of data such as running time, song, track number, etc. One bit per audio channel per frame form a serial data stream. Each audio block has a single 192 bit control word.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;C (30) Channel status bit: its structure depends on whether AES/EBU or &lt;a href="http://en.wikipedia.org/wiki/S/PDIF" title="S/PDIF"&gt;S/PDIF&lt;/a&gt; is used.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;P (31) Parity bit: for error detection. A parity bit is provided to permit the detection of an odd number of errors resulting from malfunctions in the interface. If set, it indicates an even parity.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="The_Channel_Status_Bit_in_AES.2FEBU" id="The_Channel_Status_Bit_in_AES.2FEBU"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h3 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=7" title="Edit section: The Channel Status Bit in AES/EBU"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;The Channel Status Bit in AES/EBU&lt;/span&gt;&lt;/h3&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;As stated before there is one channel status bit in each subframe, making one 192 bit word for each channel in each block. This 192 bit word is usually presented as 192/8 = 24 bytes. The contents of the channel status bit are completely different between the AES3 and SPDIF standards. In the case of AES3, the standard describes in detail how the bits have to be used. Here is an overview showing the broad aims of the 24 bytes:&lt;/span&gt;&lt;/p&gt; &lt;ul style="font-family: courier new;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;byte 0: basic control data: sample rate, compression, emphasis&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;byte 1: indicates if the audio stream is stereo, mono or some other combination&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;byte 2: audio word length&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;byte 3: used only for multichannel applications&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;byte 4: suitability of the signal as a sampling rate reference&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;byte 5: reserved&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;bytes 6 – 9 and 10 – 13: two slots of four bytes each for transmitting &lt;a href="http://en.wikipedia.org/wiki/ASCII" title="ASCII"&gt;ASCII&lt;/a&gt; characters.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;bytes 14 – 17: 4-byte/32-bit sample address, incrementing every frame&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;bytes 18 – 21: as above, but in time-of-day format (numbered from midnight)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;byte 22: contains information about the reliability of the audio block.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;byte 23: &lt;a href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check" title="Cyclic redundancy check"&gt;CRC&lt;/a&gt;. The absence of this byte implies interruption of the data stream before the end of the audio block, which is therefore ignored&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="See_also" id="See_also"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h2 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=8" title="Edit section: See also"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;See also&lt;/span&gt;&lt;/h2&gt; &lt;ul style="font-family: courier new;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/S/PDIF" title="S/PDIF"&gt;S/PDIF&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/ADAT" title="ADAT"&gt;ADAT&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES11" title="AES11"&gt;AES11&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES52" title="AES52"&gt;AES52&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES-EBU_embedded_timecode" title="AES-EBU embedded timecode"&gt;AES-EBU embedded timecode&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/MADI" title="MADI"&gt;MADI&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/AES-2id" title="AES-2id"&gt;AES-2id&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="References" id="References"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h2 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=9" title="Edit section: References"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;References&lt;/span&gt;&lt;/h2&gt; &lt;ul style="font-family: courier new;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;cite class="book" style="font-style: normal;" id="Reference-Watkinson-2001"&gt;Watkinson, John (2001). &lt;i&gt;The Art of Digital Audio Third Edition&lt;/i&gt;. Focal Press. &lt;a href="http://en.wikipedia.org/wiki/Special:BookSources/0240515870" class="internal"&gt;ISBN 0240515870&lt;/a&gt;.&lt;/cite&gt;&lt;/span&gt;&lt;span class="Z3988" title="ctx_ver=Z39.88-2004&amp;amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&amp;amp;rft.genre=book&amp;amp;rft.btitle=The+Art+of+Digital+Audio+Third+Edition&amp;amp;rft.aulast=Watkinson&amp;amp;rft.aufirst=John&amp;amp;rft.pub=Focal+Press&amp;amp;rft.isbn=0240515870"  style="font-size:85%;"&gt; &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;cite style="font-style: normal;"&gt;Watkinson, John (August 1989). "&lt;a href="http://www.aes.org/e-lib/browse.cfm?elib=5330" class="external text" title="http://www.aes.org/e-lib/browse.cfm?elib=5330" rel="nofollow"&gt;The AES/EBU Digital Audio Interface&lt;/a&gt;". &lt;i&gt;UK Conference: AES/EBU Interface&lt;/i&gt;. EBU-02.&lt;/cite&gt;&lt;/span&gt;&lt;span class="Z3988" title="ctx_ver=Z39.88-2004&amp;amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&amp;amp;rft.genre=proceeding&amp;amp;rft.btitle=UK+Conference%3A+AES%2FEBU+Interface&amp;amp;rft.atitle=The+AES%2FEBU+Digital+Audio+Interface&amp;amp;rft.aulast=Watkinson&amp;amp;rft.aufirst=John&amp;amp;rft.date=August+1989&amp;amp;rft_id=http%3A%2F%2Fwww.aes.org%2Fe-lib%2Fbrowse.cfm%3Felib%3D5330"  style="font-size:85%;"&gt; &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Emmett, John (1995). &lt;a href="http://www.ebu.ch/CMSimages/en/tec_AES-EBU_eg_tcm6-11890.pdf" class="external text" title="http://www.ebu.ch/CMSimages/en/tec_AES-EBU_eg_tcm6-11890.pdf" rel="nofollow"&gt;Engineering Guidelines: The EBU/AES Digital Audio Interface&lt;/a&gt; (PDF). &lt;a href="http://en.wikipedia.org/wiki/EBU" class="mw-redirect" title="EBU"&gt;EBU&lt;/a&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;AES-2id-2006: AES information document for digital audio engineering -- Guidelines for the use of the AES3 interface. (Downloaded from the AES standards web site; see external links)&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a name="External_links" id="External_links"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;h2 style="font-family: courier new;"&gt;&lt;span class="editsection"  style="font-size:85%;"&gt;[&lt;a href="http://en.wikipedia.org/w/index.php?title=AES/EBU&amp;amp;action=edit&amp;amp;section=10" title="Edit section: External links"&gt;edit&lt;/a&gt;]&lt;/span&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;span class="mw-headline"  style="font-size:85%;"&gt;External links&lt;/span&gt;&lt;/h2&gt; &lt;ul style="font-family: courier new;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.aes.org/standards/b_pub/aes-standards-in-print.cfm" class="external text" title="http://www.aes.org/standards/b_pub/aes-standards-in-print.cfm" rel="nofollow"&gt;Download page for AES standards&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;!--  NewPP limit report Preprocessor node count: 412/1000000 Post-expand include size: 2572/2048000 bytes Template argument size: 1195/2048000 bytes Expensive parser function count: 0/500 --&gt;  &lt;!-- Saved in parser cache with key enwiki:pcache:idhash:175426-0!1!0!default!!en!2 and timestamp 20080427124853 --&gt; &lt;div style="font-family: courier new;" class="printfooter"&gt;&lt;span style="font-size:85%;"&gt; Retrieved from "&lt;a href="http://en.wikipedia.org/wiki/AES/EBU"&gt;http://en.wikipedia.org/wiki/AES/EBU&lt;/a&gt;"&lt;/span&gt;&lt;/div&gt;    &lt;div style="font-family: courier new;" id="catlinks" class="catlinks"&gt;&lt;div id="mw-normal-catlinks"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Portal:Contents/Categorical_index" title="Portal:Contents/Categorical index"&gt;Categories&lt;/a&gt;: &lt;/span&gt;&lt;span dir="ltr"  style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Category:Audio_engineering" title="Category:Audio engineering"&gt;Audio engineering&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt; | &lt;/span&gt;&lt;span dir="ltr"  style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Category:Digital_audio" title="Category:Digital audio"&gt;Digital audio&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt; | &lt;/span&gt;&lt;span dir="ltr"  style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Category:Sound" title="Category:Sound"&gt;Sound&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt; | &lt;/span&gt;&lt;span dir="ltr"  style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Category:Broadcast_engineering" title="Category:Broadcast engineering"&gt;Broadcast engineering&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-649545711280722790?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/649545711280722790/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=649545711280722790' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/649545711280722790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/649545711280722790'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/04/aesebu-from-wikipedia-free-encyclopedia.html' title='AES/EBU From Wikipedia, the free encyclopedia'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-3865719449828067993</id><published>2008-04-23T03:40:00.001-07:00</published><updated>2008-04-23T03:49:10.468-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章'/><title type='text'>PS/2 PC键盘编程参考资料</title><content type='html'>&lt;span style="color: rgb(0, 0, 0); font-family: courier new;font-size:85%;" &gt;PS/2 PC键盘编程的参考资料&lt;/span&gt;  &lt;p style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"  align="left"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;一.电气特性&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"  align="left"&gt;&lt;span style="font-size:85%;"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/20060830/1333360.gif" height="85" width="83" /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"  align="left"&gt;  &lt;/p&gt;&lt;table  style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;" bg="" border="1" cellspacing="1"&gt;      &lt;tbody&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;1&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;DATA&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;Key Data&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;2&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;n/c&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;Not connected&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;3&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;GND&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;Gnd&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;4&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;VCC&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;Power , +5 VDC&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;5&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;CLK&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;Clock&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;6&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;n/c&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;Not connected&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;      &lt;/tbody&gt;  &lt;/table&gt;    &lt;p style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"  align="left"&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;  &lt;p style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"  align="left"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;二.数据格式&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"  align="left"&gt;  &lt;/p&gt;&lt;table style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;" bordercolordark="#ffffff" bordercolorlight="#000000"  border="1" width="100%"&gt;      &lt;tbody&gt;          &lt;tr class="main"&gt;              &lt;td align="center" width="41%"&gt;&lt;span style="font-size:85%;"&gt;1个起始位&lt;/span&gt;&lt;/td&gt;              &lt;td align="center" width="59%"&gt;&lt;span style="font-size:85%;"&gt;总是逻辑0&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr class="main"&gt;              &lt;td align="center" width="41%"&gt;&lt;span style="font-size:85%;"&gt;8个数据位&lt;/span&gt;&lt;/td&gt;              &lt;td align="center" width="59%"&gt;&lt;span style="font-size:85%;"&gt;（LSB）低位在前&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr class="main"&gt;              &lt;td align="center" width="41%"&gt;&lt;span style="font-size:85%;"&gt;1个奇偶校验位&lt;/span&gt;&lt;/td&gt;              &lt;td align="center" width="59%"&gt;&lt;span style="font-size:85%;"&gt;奇校验&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr class="main"&gt;              &lt;td align="center" width="41%"&gt;&lt;span style="font-size:85%;"&gt;1个停止位&lt;/span&gt;&lt;/td&gt;              &lt;td align="center" width="59%"&gt;&lt;span style="font-size:85%;"&gt;总是逻辑1&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr class="main"&gt;              &lt;td align="center" width="41%"&gt;&lt;span style="font-size:85%;"&gt;1个应答位&lt;/span&gt;&lt;/td&gt;              &lt;td align="center" width="59%"&gt;&lt;span style="font-size:85%;"&gt;仅用在主机对设备的通讯中&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;      &lt;/tbody&gt;  &lt;/table&gt;    &lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;表中，如果数据位中１的个数为偶数，校验位就为１；如果数据位中１的个数为奇数，校验位就为０；总之，数据位中１的个数加上校验位中１的个数总为奇数，因此总进行奇校验。&lt;/span&gt;&lt;/p&gt;  &lt;p style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"  align="left"&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new; color: rgb(0, 0, 0);" align="left"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;三.PS/2 发送数据到PC的时序&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="color: rgb(0, 0, 0); font-family: courier new;" face="courier new" align="left"&gt;&lt;span style="font-size:85%;"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/20060830/1333361.jpg" height="194" width="450" /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="color: rgb(0, 0, 0); font-family: courier new;" face="courier new" align="left"&gt;&lt;span style="font-size:85%;"&gt;键盘接口时序(a) 键盘发送时序；(b) 键盘接收时序&lt;/span&gt;&lt;/p&gt;    &lt;p style="color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;" &gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="font-family: courier new; color: rgb(0, 0, 0);" align="left"&gt;&lt;span style="color: rgb(255, 0, 0);font-size:85%;" &gt;注:在时钟的下降沿读取数据.以下可做具体写程序参考&lt;/span&gt;&lt;/p&gt;&lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span class="main1"&gt;&lt;strong&gt;从ＰＳ／２向ＰＣ机发送一个字节可按照下面的步骤进行：&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;(１)检测时钟线电平，如果时钟线为低，则延时５０μｓ；&lt;br /&gt;        (２)检测判断时钟信号是否为高，为高，则向下执行，为低，则转到(１)；&lt;br /&gt;        (３)检测数据线是否为高，如果为高则继续执行，如果为低，则放弃发送（此时ＰＣ机在向 ＰＳ／２设备发送数据，所    以ＰＳ／２设备要转移到接收程序处接收数据）；&lt;br /&gt;        (４)延时２０μｓ（如果此时正在发送起始位，则应延时４０μｓ）；&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;          (&lt;/span&gt;&lt;span style="font-size:85%;"&gt;５&lt;/span&gt;&lt;span style="font-size:85%;"&gt;)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;输出起始位（０）到数据线上。这里要注意的是：在送出每一位后都要检测时钟线，以确保ＰＣ机没有抑制ＰＳ／２设备，如果有则中止发送；&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;          (&lt;/span&gt;&lt;span style="font-size:85%;"&gt;６&lt;/span&gt;&lt;span style="font-size:85%;"&gt;)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;输出８个数据位到数据线上；&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;          (&lt;/span&gt;&lt;span style="font-size:85%;"&gt;７&lt;/span&gt;&lt;span style="font-size:85%;"&gt;)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;输出校验位；&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;          (&lt;/span&gt;&lt;span style="font-size:85%;"&gt;８&lt;/span&gt;&lt;span style="font-size:85%;"&gt;)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;输出停止位（１）；&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;          (&lt;/span&gt;&lt;span style="font-size:85%;"&gt;９&lt;/span&gt;&lt;span style="font-size:85%;"&gt;)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;延时３０μｓ（如果在发送停止位时释放时钟信号则应延时５０μｓ）；&lt;/span&gt;&lt;/p&gt;  &lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;通过以下步骤可发送单个位：&lt;br /&gt;        （１）准备数据位（将需要发送的数据位放到数据线上）；&lt;br /&gt;        （２）延时２０μｓ；&lt;br /&gt;        （３）把时钟线拉低；&lt;br /&gt;        （４）延时４０μｓ；&lt;br /&gt;        （５）释放时钟线；&lt;br /&gt;        （６）延时２０μｓ。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;ＰＳ／２设备从ＰＣ机接收一个字节&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;由于ＰＳ／２设备能提供串行同步时钟，因此，如果ＰＣ机发送数据，则ＰＣ机要先把时钟线和数据线置为请求发送的状态。ＰＣ机通过下拉时钟线大于１００μｓ 来抑制通讯，并且通过下拉数据线发出请求发送数据的信号，然后释放时钟。当ＰＳ／２设备检测到需要接收的数据时，它会产生时钟信号并记录下面８个数据位和 一个停止位。主机此时在时钟线变为低时准备数据到数据线，并在时钟上升沿锁存数据。而ＰＳ／２设备则要配合ＰＣ机才能读到准确的数据。具体连接步骤如下：&lt;br /&gt;（１）等待时钟线为高电平。&lt;br /&gt;        （２）判断数据线是否为低，为高则错误退出，否则继续执行。&lt;br /&gt;        （３）读地址线上的数据内容，共８个ｂｉｔ，每读完一个位，都应检测时钟线是否被ＰＣ机拉低，如果被拉低则要中止接收。&lt;br /&gt;        （４）读地址线上的校验位内容，１个ｂｉｔ。&lt;br /&gt;        （５）读停止位。&lt;br /&gt;        （６）如果数据线上为０（即还是低电平），ＰＳ／２设备继续产生时钟，直到接收到１且产生出错信号为止（因为停止位是１，如果ＰＳ／２设备没有读到停止位，则表明此次传输出错）。       &lt;br /&gt;        （７ 输出应答位。&lt;br /&gt;        （８） 检测奇偶校验位，如果校验失败，则产生错误信号以表明此次传输出现错误。&lt;br /&gt;        （９）延时４５ μｓ，以便ＰＣ机进行下一次传输。&lt;/span&gt;&lt;/p&gt;    &lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;读数据线的步骤如下：&lt;br /&gt;（１）延时２０μｓ；&lt;br /&gt;        （２）把时钟线拉低??&lt;br /&gt;        （３）延时４０μｓ??&lt;br /&gt;        （４）释放时钟线??&lt;br /&gt;        （５）延时２０μｓ??&lt;br /&gt;        （６）读数据线。&lt;/span&gt;&lt;/p&gt;    &lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;下面的步骤可用于发出应答位；&lt;/span&gt;&lt;/p&gt;&lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;（１）延时１５μｓ；&lt;br /&gt;        （２）把数据线拉低；&lt;br /&gt;        （３）延时５μｓ；&lt;br /&gt;        （４）把时钟线拉低；&lt;br /&gt;        （５）延时４０μｓ；&lt;br /&gt;        （６）释放时钟线；&lt;br /&gt;        （７）延时５μｓ；&lt;br /&gt;        （８）释放数据线。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;四.键盘返回值介绍:&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;注意:键盘的返回值并不是和一般ASCII码相对应!&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;键盘的处理器如果发现有键被按下释放或按住键盘将发送扫描码的信息包到计算机扫描码有两种 不同的类型通码和断码当一个键被按下或按住就发送通码当一个键被释放就发送断码每个按键被分配了唯一的通码和断码这样主机通过查找唯一的扫描码就可以测定 是哪个按键每个键一整套的通断码组成了扫描码集有三套标准的扫描码集分别是第一套第二套和第三套所有现代的键盘默认使用第二套扫描码&lt;br /&gt;     虽然多数第二套通码都只有一个字节宽但也有少数扩展按键的通码是两字节或四字节宽这类的通码第一个字节总是为E0h&lt;br /&gt;     正如键按下通码就被发往计算机一样只要键一释放断码就会被发送每个键都有它自己唯一的通码它们也都有唯一的断码幸运的是你不用总是通过查表来找出按键的断 码在通码和断码之间存在着必然的联系多数第二套断码有两字节长它们的第一个字节是F0h 第二个字节是这个键的通码扩展按键的断码通常有三个字节它们前两个字节是E0h,F0h 最后一个字节是这个按键通码的最后一个字节作为一个例子我在下面列出了几个按键的第二套通码和断码&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;  &lt;/p&gt;&lt;table face="courier new" style="color: rgb(0, 0, 0); font-family: courier new;" bg="" border="1" cellspacing="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th bg="" align="center"&gt;&lt;p&gt;No.&lt;br /&gt;&lt;/p&gt;              &lt;/th&gt;              &lt;th bg="" align="center"&gt;              &lt;p&gt;key   &lt;br /&gt;&lt;/p&gt;              &lt;/th&gt;              &lt;th bg="" align="center"&gt;通碼(第二套)&lt;br /&gt;&lt;/th&gt;              &lt;th bg="" align="center"&gt;              &lt;p&gt;斷碼(第二套)&lt;br /&gt;&lt;/p&gt;              &lt;/th&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;1&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;"A"&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;1C&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;F0 1C&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;2&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;"5"&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;2E&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;F0 2E&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;3&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;"F10"&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;09&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;F0 09&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;4&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;Right Arrow&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;E0 74&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;E0 F0 74&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;5&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;Right "Ctrl"&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;E0 14&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:85%;" &gt;E0 F0 14&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;      &lt;/tbody&gt;  &lt;/table&gt;    &lt;div style="text-align: left; color: rgb(0, 0, 0); font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;&lt;br /&gt;一个键盘发送值的例子:&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;p  style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;      通码和断码是以什么样的序列发送到你的计算机从而使得字符G 出现在你的字处理软件里的呢因为这是一个大写字母需要发生这样的事件次序按下Shift 键按下G键释放G 键释放Shift 键与这些时间相关的扫描码如下Shift 键的通码12hG 键的通码34h G 键的断码F0h 34h Shift 键的断码F0h 12h 因此发送到你的计算机的数据应该是&lt;/span&gt;&lt;/p&gt;  &lt;p style="text-indent: 30px; font-family: courier new; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;12h 34h F0h 34h F0h 12h&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p face="courier new" style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;五:第二套扫描码:&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style="text-indent: 30px; text-align: left; color: rgb(0, 0, 0); font-family: courier new;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;101 102 和104 键的键盘:&lt;/span&gt;&lt;/p&gt;  &lt;p face="courier new" style="text-indent: 30px; color: rgb(0, 0, 0); font-family: courier new;"&gt;  &lt;/p&gt;&lt;table face="courier new" style="color: rgb(0, 0, 0); font-family: courier new;" bg="" border="1" cellspacing="1"&gt;      &lt;tbody&gt;          &lt;tr&gt;              &lt;th bg="" align="center"&gt;              key&lt;br /&gt;&lt;/th&gt;&lt;th bg="" align="center"&gt;              通碼&lt;br /&gt;&lt;/th&gt;&lt;th bg="" align="center"&gt;              斷碼&lt;br /&gt;&lt;/th&gt;                                          &lt;td style="font-weight: bold; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;th bg="" align="center"&gt;              key&lt;br /&gt;&lt;/th&gt;&lt;th bg="" align="center"&gt;              通碼&lt;br /&gt;&lt;/th&gt;&lt;th bg="" align="center"&gt;              斷碼&lt;br /&gt;&lt;/th&gt;                                          &lt;td style="font-weight: bold; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;th bg="" align="center"&gt;              key&lt;br /&gt;&lt;/th&gt;&lt;th bg="" align="center"&gt;              通碼&lt;br /&gt;&lt;/th&gt;&lt;th bg="" align="center"&gt;              斷碼&lt;br /&gt;&lt;/th&gt;                                      &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="font-size:85%;"&gt;A&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;1C&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;F0 1C&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;9&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;46&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 46&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;[&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;54 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 54 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="font-size:85%;"&gt;B&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;32&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;F0 32&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;`&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;0E&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 0E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;INSERT&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 70 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 70&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="font-size:85%;"&gt;C&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;21&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;F0 21&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;-&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;4E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 4E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;HOME&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 6C &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 6C&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;D&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;23&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;F0 23&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;=&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;55 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 55 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;PG UP&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 7D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 7D&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;24&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;F0 24&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;\&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;5D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 5D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;DELETE&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 71 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 71 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;2B&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 2B&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;BKSP&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;66 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 66 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;END&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 69 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 69 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;G&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;34 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 34 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;SPACE&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;29 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 29 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;PG DN&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 7A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 7A &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;H &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;33 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 33 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;TAB&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;0D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 0D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;U ARROW&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 75 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 75 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;I&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;43 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 43 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;CAPS&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;58 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 58 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;L ARROW&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 6B &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 6B &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;J&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;3B &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 3B &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;L SHFT &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;12 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 12 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;D ARROW&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 72&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 72 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;K &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;42 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 42 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;L CTRL&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;14 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 14 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;R ARROW&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 74&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 74 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;L &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;4B&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 4B &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;L GUI&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 1F &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 1F&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;NUM&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;77 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0  77&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;M &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;3A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 3A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;L ALT&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;11 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 11 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP /&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 4A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 4A &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;N &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;31 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 31 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;R SHFT &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;59 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 59 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP *&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;7C&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0  7C&lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;O &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;44 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 44 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;R CTRL &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 14 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 14 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP -&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;7B&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 7B &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;P &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;4D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 4D&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;R GUI&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 27 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 27 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP +&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;79&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 79 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;Q &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;15 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 15 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;R ALT&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 11 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 11 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP EN&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 5A&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 5A &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;R &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;2D&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 2D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;APPS&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 2F &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0 2F &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;71&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 71 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;S &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;1B &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 1B &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;ENTER&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;5A&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 5A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 0&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;70&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 70 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;T &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;2C &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 2C &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;ESC&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;76 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 76 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 1&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;69&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 69 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;U &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;3C&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 3C &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F1&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;05 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 05 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 2 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;72&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 72 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;V &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;2A&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 2A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F2 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;06&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 06 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 3 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;7A&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 7A &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;W &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;1D&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 1D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F3 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;04 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 04 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 4 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;6B&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 6B &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;X &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;22&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 22 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F4 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;0C &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 0C &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 5 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;73&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 73 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;Y &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;35 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 35 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F5 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;03 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 03 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 6 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;74&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 74 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;Z &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;1A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 1A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F6 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;0B &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 0B &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 7 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;6C &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 6C &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;0&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;45 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 45 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F7 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;83 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 83 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 8 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;75&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 75 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;1 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;16 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 16 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F8 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;0A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 0A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;KP 9 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;7D&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 7D &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;2 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;1E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 1E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F9 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;01 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 01 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;]&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;58&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 58 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;3 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;26 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 26 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F10 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;09 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 09 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;;&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;4C&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 4C &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;4 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;25 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 25 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F11 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;78 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 78 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;'&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;52&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 52 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;5 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;2E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 2E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F12 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;07 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 07 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;,&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;41&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 41 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;6 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;36&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 36 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;PRNT&lt;br /&gt;SCRN&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 12&lt;br /&gt;E0 7C&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0 F0&lt;br /&gt;7C E0&lt;br /&gt;F0 12 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;.&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;49&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 49 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;7 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;3D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 3D &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;SCROLL&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;7E&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0,7E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;/&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;4A&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 4A &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;8 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;3E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;F0 3E &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;PAUSE&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E1 14 77&lt;br /&gt;E1 F0 14&lt;br /&gt;F0 77&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; -NONE-&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/td&gt;          &lt;/tr&gt;      &lt;/tbody&gt;  &lt;/table&gt;    &lt;div style="text-align: left; color: rgb(0, 0, 0); font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;ACPI 扫描码:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style="text-indent: 30px; font-family: courier new; color: rgb(0, 0, 0);"&gt;  &lt;/p&gt;&lt;table face="courier new" style="color: rgb(0, 0, 0); font-family: courier new;" bg="" border="1" cellspacing="1"&gt;      &lt;tbody&gt;          &lt;tr&gt;              &lt;th bg="" align="center"&gt;              key&lt;br /&gt;&lt;/th&gt;              &lt;th bg="" align="center"&gt;              通碼&lt;br /&gt;&lt;/th&gt;              &lt;th bg="" align="center"&gt;              斷碼&lt;br /&gt;&lt;/th&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="font-size:85%;"&gt;Power&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, 37&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, F0, 37&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="font-size:85%;"&gt;Sleep&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, 3F&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, F0, 3F&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="font-size:85%;"&gt;Wake&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, 5E&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, F0, 5E&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;      &lt;/tbody&gt;  &lt;/table&gt;    &lt;div style="text-align: left; color: rgb(0, 0, 0); font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;Windows 多媒体扫描码:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style="text-indent: 30px; font-family: courier new; color: rgb(0, 0, 0);"&gt;  &lt;/p&gt;&lt;table face="courier new" style="color: rgb(0, 0, 0); font-family: courier new;" bg="" border="1" cellspacing="1"&gt;      &lt;tbody&gt;          &lt;tr&gt;&lt;th bg="" align="center"&gt;              key&lt;br /&gt;&lt;/th&gt;&lt;th bg="" align="center"&gt;              通碼&lt;br /&gt;&lt;/th&gt;&lt;th bg="" align="center"&gt;              斷碼&lt;br /&gt;&lt;/th&gt;&lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="font-size:85%;"&gt;Next Track&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, 4D&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, F0, 4D&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="font-size:85%;"&gt;Previous Track&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, 15&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, F0, 15&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="font-size:85%;"&gt;Stop&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, 3B&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;              &lt;td&gt;              &lt;p&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;E0, F0, 3B&lt;/span&gt;&lt;/p&gt;              &lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;Play/Pause&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 34&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 34 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;Mute&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 23 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 23 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;Volume Up &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 32&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 32 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;Volume Down &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 21 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 21 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;Media Select &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 50 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 50 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E-Mail&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 48 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 48 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;Calculator&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 2B &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 2b &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;My Computer&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 40 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 40 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;WWW Search &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 10 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 10 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;WWW Home &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 3A &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 3a &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;WWW Back&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 38 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 38 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;WWW Forward&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 30 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 20 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;WWW Stop&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 28 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 28 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;WWW Refresh&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 20&lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 20 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;          &lt;tr&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;WWW Favorites &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, 18 &lt;/span&gt;&lt;/td&gt;              &lt;td&gt;&lt;span style="font-size:85%;"&gt;E0, F0, 18 &lt;/span&gt;&lt;/td&gt;          &lt;/tr&gt;      &lt;/tbody&gt;  &lt;/table&gt;   &lt;p style="font-family: courier new; color: rgb(0, 0, 0);" class="pageview"&gt;  &lt;/p&gt; &lt;!--Zoom end --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-3865719449828067993?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/3865719449828067993/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=3865719449828067993' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3865719449828067993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3865719449828067993'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/04/ps2-pc.html' title='PS/2 PC键盘编程参考资料'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-463544405154893234</id><published>2008-04-23T03:39:00.000-07:00</published><updated>2008-04-23T03:40:09.002-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章'/><title type='text'>PS/2接口协议解析及应用</title><content type='html'>&lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;ps/2接口标准的发展过程&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;        随着计算机工业的发展，作为计算机最常用输入设备的键盘也日新月异。1981年IBM推出了IBM pc/XT键盘及其接口标准。该标准定义了83键，采用5脚DIN连接器和简单的串行协议。实际上，第一套键盘扫描码集并没有主机到键盘的命令。为此， 1984年IBM推出了IBM AT键盘接口标准。该标准定义了84~101键，采用5脚DIN连接器和双向串行通讯协议，此协议依照第二套键盘扫描码集设有8个主机到键盘的命令。到了 1987年，IBM又推出了ps/2键盘接口标准。该标准仍旧定义了84~101键，但是采用6脚mini-DIN连接器，该连接器在封装上更小巧，仍然 用双向串行通讯协议并且提供有可选择的第三套键盘扫描码集，同时支持17个主机到键盘的命令。现在，市面上的键盘都和ps/2及AT键盘兼容，只是功能不 同而已。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;ps/2接口硬件&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.dzkf.cn/upimg/allimg/0609/1_01133811.JPG" target="_blank"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/0609/1_01133811.JPG" border="0" height="346" width="458" /&gt;&lt;/a&gt;&lt;br /&gt;2.1 物理连接器&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;一般，具有五脚连接器的键盘称之为AT键盘，而具有六脚mini-DIN连接器的键盘则称之为ps/2键盘。其实这两种连接器都只有四个脚有意义。 它们分别是Clock(时钟脚)、DATA(数据脚)、+5V(电源脚)和Ground(电源地)。在ps/2键盘与pc机的物理连接上只要保证这四根线 一一对应就可以了。ps/2键盘靠pc的ps/2端口提供+5V电源，另外两个脚Clock(时钟脚)和DATA(数据脚)都是集电极开路的，所以必须接 大阻值的上拉电阻。它们平时保持高电平，有输出时才被拉到低电平，之后自动上浮到高电平。现在比较常用的连接器如图1所示。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;2.2 电气特性&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;ps/2 通讯协议是一种双向同步串行通讯协议。通讯的两端通过Clock(时钟脚)同步，并通过DATA(数据脚)交换数据。任何一方如果想抑制另外一方通讯时， 只需要把Clock(时钟脚)拉到低电平。如果是pc机和ps/2键盘间的通讯，则pc机必须做主机，也就是说，pc机可以抑制ps/2键盘发送数据，而 ps/2键盘则不会抑制pc机发送数据。一般两设备间传输数据的最大时钟频率是33kHz，大多数ps/2设备工作在10~20kHz。推荐值在 15kHz左右，也就是说，Clock(时钟脚)高、低电平的持续时间都为40μs。每一数据帧包含11~12个位，具体含义如表1所列。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;表1 数据帧格式说明&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;1个起始位 总是逻辑0&lt;br /&gt;8个数据位 （LSB）低位在前&lt;br /&gt;1个奇偶校验位 奇校验&lt;br /&gt;1个停止位 总是逻辑1&lt;br /&gt;1个应答位 仅用在主机对设备的通讯中&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;表中，如果数据位中1的个数为偶数，校验位就为1；如果数据位中1的个数为奇数，校验位就为0；总之，数据位中1的个数加上校验位中1的个数总为奇数，因此总进行奇校验。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;2.3 ps/2设备和pc机的通讯&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;ps/2 设备的Clock(时钟脚)和DATA(数据脚)　都是集电极开路的，平时都是高电平。当ps/2设备等待发送数据时，它首先检查Clock(时钟脚)以 确认其是否为高电平。如果是低电平，则认为是pc机抑制了通讯，此时它必须缓冲需要发送的数据直到重新获得总线的控制权(一般ps/2键盘有16个字节的 缓冲区，而ps/2鼠标只有一个缓冲区仅存储最后一个要发送的数据)。如果Clock(时钟脚)为高电平，ps/2设备便开始将数据发送到pc机。一般都 是由ps/2设备产生时钟信号。发送时一般都是按照数据帧格式顺序发送。其中数据位在Clock(时钟脚)为高电平时准备好，在Clock(时钟脚)的下 降沿被pc机读入。ps/2设备到pc机的通讯时序如图2所示。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;当时钟频率为15kHz时，从Clock(时钟脚)的上升沿到数据位转变时间至少要5μｓ。数据变化到Clock(时钟脚)下降沿的时间至少也有5 μｓ，但不能大于25 μｓ，这是由ps/2通讯协议的时序规定的。如果时钟频率是其它值，参数的内容应稍作调整。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;上述讨论中传输的数据是指对特定键盘的编码或者对特定命令的编码。一般采用第二套扫描码集所规定的码值来编码。其中键盘码分为通码(make)和断 码 (Break)。通码是按键接通时所发送的编码，用两位十六进制数来表示，断码通常是按键断开时所发送的编码，用四位十六进制数来表示。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;3 ps/2接口的嵌入式软件编程方法&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;ps/2设备主要用于产生同步时钟信号和读写数据。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;3．1 ps/2向pc机发送一个字节&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.dzkf.cn/upimg/allimg/0609/1_01133852.JPG" target="_blank"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/0609/1_01133852.JPG" border="0" height="213" width="434" /&gt;&lt;/a&gt;&lt;br /&gt;从ps/2向pc机发送一个字节可按照下面的步骤进行：&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(1)检测时钟线电平，如果时钟线为低，则延时50μｓ；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(2)检测判断时钟信号是否为高，为高，则向下执行，为低，则转到(1)；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(3)检测数据线是否为高，如果为高则继续执行，如果为低，则放弃发送(此时pc机在向ps/2设备发送数据，所以ps/2设备要转移到接收程序处接收数据)；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(４)延时20μｓ(如果此时正在发送起始位，则应延时４0μｓ)；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(5)输出起始位(0)到数据线上。这里要注意的是：在送出每一位后都要检测时钟线，以确保pc机没有抑制ps/2设备，如果有则中止发送；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(６)输出8个数据位到数据线上；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(７)输出校验位；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(8)输出停止位(1)；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(９)延时30μｓ(如果在发送停止位时释放时钟信号则应延时50μｓ)；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;通过以下步骤可发送单个位：&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(1)准备数据位(将需要发送的数据位放到数据线上)；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(2)延时20μｓ；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(3)把时钟线拉低；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(４)延时４0μｓ；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(5)释放时钟线；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(６)延时20μｓ。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;3．2 ps/2设备从pc机接收一个字节&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;由于ps/2设备能提供串行同步时钟，因此，如果pc机发送数据，则pc机要先把时钟线和数据线置为请求发送的状态。pc机通过下拉时钟线大于 100μｓ来抑制通讯，并且通过下拉数据线发出请求发送数据的信号，然后释放时钟。当ps/2设备检测到需要接收的数据时，它会产生时钟信号并记录下面8 个数据位和一个停止位。主机此时在时钟线变为低时准备数据到数据线，并在时钟上升沿锁存数据。而ps/2设备则要配合pc机才能读到准确的数据。具体连接 步骤如下：&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(1)等待时钟线为高电平。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(2)判断数据线是否为低，为高则错误退出，否则继续执行。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(3)读地址线上的数据内容，共8个bit，每读完一个位，都应检测时钟线是否被pc机拉低，如果被拉低则要中止接收。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(４)读地址线上的校验位内容，1个bit。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(5)读停止位。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(６)如果数据线上为0(即还是低电平)，ps/2设备继续产生时钟，直到接收到1且产生出错信号为止(因为停止位是1，如果ps/2设备没有读到停止位，则表明此次传输出错)。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(７ 输出应答位。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(8) 检测奇偶校验位，如果校验失败，则产生错误信号以表明此次传输出现错误。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(９)延时４5 μｓ，以便pc机进行下一次传输。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;读数据线的步骤如下：&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(1)延时20μｓ；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(2)把时钟线拉低&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(3)延时４0μｓ&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(４)释放时钟线&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(5)延时20μｓ&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(６)读数据线。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;下面的步骤可用于发出应答位；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(1)延时15μｓ；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(2)把数据线拉低；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(3)延时5μｓ；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(４)把时钟线拉低；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(5)延时４0μｓ；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(６)释放时钟线；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(７)延时5μｓ；&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;(8)释放数据线。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.dzkf.cn/upimg/allimg/0609/1_01133930.JPG" target="_blank"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/0609/1_01133930.JPG" border="0" height="544" width="517" /&gt;&lt;/a&gt;&lt;br /&gt;４　用于工控机的双键盘设计&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;工控机通常要接标准键盘，但是为了方便操作，常常需要外接一个专用键盘。此实例介绍了在工控pc机到ps/2总线上再接入一个自制专用键盘的应用方法。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;该设计应能保证两个键盘单独工作，而且相互不能影响。因此，不能直接把专用键盘和标准键盘一起接到工控pc的ps/2口。鉴于这种情况，本设计使用 模拟开关ＣＤ４052并通过时分复用工控pc的ps/2口，来使在同一个时刻只有一个键盘有效，从而解决上述问题。其硬件原理图如图3所示。其中Ｐ2口和 Ｐ1口用于键盘扫描电路(图中未画出)，p0．0为数据端，p0．1为时钟端，p0．2为模拟开关选通端。由于专用键盘不需要接收工控pc机的命令，所以 软件中并不需要写这部分相应的代码。&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;通过软件可在专用键盘复位后把p0．2清0，以使模拟开关ＣＤ４052打开相应的通道。这时工控pc的标准键盘将开始工作。标准键盘可以完成工控 pc刚启动时对外设检测的应答。复位后的专用键盘不停地扫描有没有按键，如果有键按下则识别按键，并且按照预先的设计进行编码，同时调用发送程序并通过 ps/2口发送到工控pc。此时模拟开关关闭相应通道(将p0．2置1)，专用键盘接入工控pc ps/2口的时钟线和数据线而工作，但标准键盘被模拟开关从ps/2的时钟线和数据线中断而不工作，这样，双键盘便可时分复用同一个工控pc机的ps/2 口。相应的发送子程序如下：&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;#define DATA p00    用p0．0做数据线&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;#define CLK p01         用p0．1做时钟线&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;#define INHIbit p02   用p0．2做ＣＤ４052的INH端&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;#define PORTR  p1     用P1口做读入口&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;#define PORTW  p2      用P2口做写出口 可以实现６４个自定义键&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;void send(uchar x) /*   function for send a char data*/&lt;br /&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;  uchar i,temp,char_temp;&lt;br /&gt;  bit flag_check =1;&lt;br /&gt;  INHIBIT =1;   //disable standard keyboard&lt;br /&gt;  delay_ms(3);&lt;br /&gt;  temp = x;&lt;br /&gt;  for( i=0; i&lt;8; i++)  //find the number of 1 in this uchar x is odd or not&lt;br /&gt;  {&lt;br /&gt;     char_temp = temp &amp;amp; 0x01;&lt;br /&gt;     if(char_temp == 0x01)&lt;br /&gt;     {&lt;br /&gt;    flag_check =!flag_check;&lt;br /&gt;     }&lt;br /&gt;     temp = temp &gt;&gt;1;&lt;br /&gt;  }&lt;br /&gt;  CLK =1;   //send 1 to P1 then read P1&lt;br /&gt;  while(!CLK)    //if CLK is low wait&lt;br /&gt;  {&lt;br /&gt;     ;&lt;br /&gt;  }&lt;br /&gt;  CLK =1;&lt;br /&gt;  DATA =1; //send 1 to P1 then read P1&lt;br /&gt;  if(CLK ==1)&lt;br /&gt;  {&lt;br /&gt;    delay_us(30);&lt;br /&gt;  }&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;  if(CLK==1 &amp;amp;&amp;amp; DATA==1)   //send data&lt;br /&gt;  {&lt;br /&gt;     DATA =0;   //start bit 0&lt;br /&gt;     delay_us(10);&lt;br /&gt;     CLK =0;&lt;br /&gt;     delay_us(5);&lt;br /&gt;     temp =x;&lt;br /&gt;     for(i=0;i&lt;8;i++)  //send 8 bits LSB first&lt;br /&gt;     {&lt;br /&gt;         CLK =1;&lt;br /&gt;         delay_us(5);&lt;br /&gt;         char_temp = temp &amp;amp; 0x01;&lt;br /&gt;         if ( char_temp == 0x01)&lt;br /&gt;         {&lt;br /&gt;              DATA =1;&lt;br /&gt;         }&lt;br /&gt;         else&lt;br /&gt;         {&lt;br /&gt;              DATA =0;&lt;br /&gt;         }&lt;br /&gt;         //DATA=(bit)(temp&amp;amp;0x01);&lt;br /&gt;         //LSB&lt;br /&gt;         delay_us(10);&lt;br /&gt;         CLK = 0;&lt;br /&gt;         delay_us(5);&lt;br /&gt;         temp = temp&gt;&gt;1;&lt;br /&gt;     }&lt;br /&gt;     CLK = 1; //send check bit&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;     delay_us(5);&lt;br /&gt;     DATA = flag_check;&lt;br /&gt;     delay_us(10);&lt;br /&gt;     CLK = 0;&lt;br /&gt;     delay_us(5);&lt;br /&gt;     CLK =1;    //send stop bit&lt;br /&gt;    delay_us(5);&lt;br /&gt;     DATA =1;&lt;br /&gt;     dalay_us(10);&lt;br /&gt;     CLK = 0;&lt;br /&gt;     delay_us(5);&lt;br /&gt;    CLK  =1;&lt;br /&gt;     delay_us(30);&lt;br /&gt;     CLK =1;&lt;br /&gt;     DATA =1 ;   //send 1 to P1 then read P1&lt;br /&gt;     if(CLK ==1 &amp;amp;&amp;amp; DATA == 0)&lt;br /&gt;     {&lt;br /&gt;          return ;   //pc is sending data to mcu,goto&lt;br /&gt;                     //receiving function&lt;br /&gt;     }&lt;br /&gt;      INHIBIT = 0;  //enable standard keyboard&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt; &lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;5　结论&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;        ps/2 接口协议是现在大多数键盘、鼠标与pc机通讯的标准协议。其中鼠标对pc机的通讯更为简单，只是传输数据的内容不一样而已。充分理解ps/2接口协议，可 以帮助设计者自主开发一些工控机上的专用键盘等外设，并能够按照用户的要求开发出专用的多功能键盘。该工控机的双键盘设计目前已被某工控公司所采纳，并已 作为组件加入到产品当中。&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-463544405154893234?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/463544405154893234/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=463544405154893234' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/463544405154893234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/463544405154893234'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/04/ps2_4294.html' title='PS/2接口协议解析及应用'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-3389984924641315656</id><published>2008-04-23T03:37:00.000-07:00</published><updated>2008-04-23T03:39:27.328-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章'/><title type='text'>PS/2鼠标接口的设计与实现</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;当前嵌入式系统技术已得到了广泛应用,但传统嵌入式系统的人机接口多采用小键盘操作的文本菜单方式,用户操作较为不便｡本文介绍了一种利用PS/2接口鼠 标,在点阵LCD的单片机系统上实现图形化用户界面的方案｡用窗口菜单和图形按钮取代了传统的键盘操作,具有成本低､效果好等特点,具有很强的实用性｡&lt;/span&gt;&lt;/span&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;1 PS/2接口和协议&lt;/strong&gt; &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;1.1 接口的物理特性 &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    PS/2接口用于许多现代的鼠标和键盘,由IBM最初开发和使用｡物理上的PS/2接口有两种类型的连接器:5脚的DIN和6脚的mini-DIN｡图1就是两种连接器的引脚定义｡使用中,主机提供+5V电源给鼠标,鼠标的地连接到主机电源地上｡&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt; &lt;a target="_blank" href="http://www.dzkf.cn/upimg/allimg/0709/1_11170303.JPG"&gt;&lt;img alt="PS/2接口引脚定义" src="http://www.dzkf.cn/upimg/allimg/0709/1_11170303.JPG" border="0" height="203" width="572" /&gt;&lt;/a&gt;&lt;/span&gt; &lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;1.2 接口协议原理 &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    PS/2鼠标接口采用一种双向同步串行协议｡即每在时钟线上发一个脉冲,就在数据线上发送一位数据｡在相互传输中,主机拥有总线控制权,即它可以在任何时 候抑制鼠标的发送｡方法是把时钟线一直拉低,鼠标就不能产生时钟信号和发送数据｡在两个方向的传输中,时钟信号都是由鼠标产生,即主机不产生通信时钟信 号｡&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    如果主机要发送数据,它必须控制鼠标产生时钟信号｡方法如下:主机首先下拉时钟线至少100μs抑制通信,然后再下拉数据线,最后释放时钟线｡通过这一时 序控制鼠标产生时钟信号｡当鼠标检测到这个时序状态,会在10ms内产生时钟信号｡如图3中 A 时序段｡主机和鼠标之间,传输数据帧的时序如图2､图3所示｡2.2 数据包结构在主机程序中,利用每个数据位的时钟脉冲触发中断,在中断例程中实现数据位的判断和接收｡在实验过程中,通过合适的编程,能够正确控制并接收鼠 标数据｡但该方案有一点不足,由于每个CLOCK都要产生一次中断,中断频繁,需要耗用大量的主机资源｡&lt;br /&gt;&lt;a target="_blank" href="http://www.dzkf.cn/upimg/allimg/0709/1_11170409.JPG"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/0709/1_11170409.JPG" border="0" height="168" width="543" /&gt;&lt;/a&gt;  &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt; &lt;a target="_blank" href="http://www.dzkf.cn/upimg/allimg/0709/1_11170446.JPG"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/0709/1_11170446.JPG" border="0" height="200" width="532" /&gt;&lt;/a&gt;&lt;/span&gt; &lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;2 PS/2鼠标的工作模式和协议数据包格式&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;2.1 PS/2鼠标的四种工作模式 &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    PS/2鼠标的四种工作模式是:Reset模式,当鼠标上电或主机发复位命令 0xFF给它时进入这种模式;Stream模式鼠标的默认模式,当鼠标上电或复位完成后,自动进入此模式,鼠标基本上以此模式工作;Remote模式,只 有在主机发送了模式设置命令 0xF0后,鼠标才进入这种模式;Wrap模式,这种模式只用于测试鼠标与主机连接是否正确｡ &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    PS/2鼠标在工作过程中,会及时把它的状态数据发送给主机｡发送的数据包格式如表1所示｡&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a target="_blank" href="http://www.dzkf.cn/upimg/allimg/0709/1_11170616.JPG"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/0709/1_11170616.JPG" border="0" height="138" width="641" /&gt;&lt;/a&gt; &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    Byte1中的Bit0､Bit1､Bit2分别表示左､右､中键的状态,状态值0表示释放,1表示按下｡Byte2和Byte3分别表示X轴和Y轴方向 的移动计量值,是二进制补码值｡Byte4的低四位表示滚轮的移动计量值,也是二进制补码值,高四位作为扩展符号位｡这种数据包由带滚轮的三键三维鼠标产 生｡若是不带滚轮的三键鼠标,产生的数据包没有Byte4 其余的相同｡&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;3 设计与实现&lt;/strong&gt; &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;3.1 接口设计 &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    因为PS/2鼠标接口采用双向同步串行协议,时钟脉冲信号 以下皆称CLOCK 总是由鼠标产生｡因此,可以考虑这种方案:鼠标的CLOCK接主机的一外中断线,数据线 以下皆称DATA 接主机的某一I/O口线,如图4所示｡&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a target="_blank" href="http://www.dzkf.cn/upimg/allimg/0709/1_11170725.JPG"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/0709/1_11170725.JPG" border="0" height="167" width="410" /&gt;&lt;/a&gt;  &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    由于鼠标与主机之间以双向同步串行协议传送数据,若不考虑CLOCK,仅考虑DATA,则其数据帧的时序与单片机的UART异步串行时序类似｡所以,采用 了另一种方案:鼠标的CLOCK仍旧接主机的外中断,但鼠标的DATA接UART的接收脚RxD ｡参照图4DATA改接RxD｡在初始化过程中,主机利用CLOCK的外中断和RxD脚的I/O口线功能实现数据的传输｡初始化完成后,切换到RxD功能 即UART的接收引脚功能｡因为鼠标已处于Stream模式的工作状态,这时鼠标能主动发送数据｡这样,主机可以在每收到一帧数据时才中断一次｡中断次数 大大降低,减少了主机资源的耗用｡&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    不过,在此方案中,必须实现另一个功能:主机波特率的自适应｡因为PS/2接口的鼠标一般工作在10kHz~20kHz时钟频率｡不同厂家制造的鼠标工作 的时钟频率不同｡嵌入设备主机要做到与不同鼠标的波特率同步和自适应,才能够正确接收鼠标传送来的数据｡波特率的自适应是这样实现:鼠标上电自检时会产生 一串时钟脉冲,利用鼠标时钟脉冲产生的中断,结合主机的定时器测量时钟脉冲周期,可以得出所用鼠标的时钟频率,进而求出波特率｡通过设置相应的波特率寄存 器,实现了波特率的自适应｡&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;3.2 软件实现&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt; 软件实现原理框图如图5所示｡&lt;br /&gt;&lt;a target="_blank" href="http://www.dzkf.cn/upimg/allimg/0709/1_11170809.JPG"&gt;&lt;img alt="" src="http://www.dzkf.cn/upimg/allimg/0709/1_11170809.JPG" border="0" height="305" width="649" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;(1)鼠标初始化 &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    最简单的初始化就是当鼠标上电自检完成后,主机给鼠标发送一个使能鼠标数据传送命令字节 (0xf4),鼠标就会在默认设置状态下工作｡主机也可实现自定义初始化,如:复位三次(Snd_CMD(0xff),Snd_CMD(0xff), Snd_CMD(0xff);设置采样率:Snd_CMD(0xf3),Snd_CMD(0x0a);设置解析度(2点/毫米):Snd_CMD (0xe8),Snd_CMD(0x01);设置缩放比例(1:1):Snd_CMD(0xe6);使能鼠标数据传送:Snd_CMD(0xf4)｡鼠标 每收到一个命令字节都会给出一个应答字节(0xfa)｡ &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;(2)两种方案的实现过程 &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    两种方案的软件实现过程基本相同｡只是后一种方案中,初始化时还要实现主机波特率的自适应,关闭时钟脉冲中断和打开串口中断｡此后主机利用UART的接收功能接收鼠标数据｡ &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;(3)图形化人机接口(GUI)的实现 &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    在点阵式LCD显示屏上实现图形化的人机接口界面,主要有两个方面:一个是菜单图标的实现;另一个是鼠标光标的实现｡实现菜单图标,显示屏一般工作在图形 显示模式｡菜单图标有正常显示状态和反显状态,它们都用函数实现:voidDraw_ICON(signed int xICON, signed int yICON,unsigned char *pDatICON)｡xICONyICON是图标所在位置的左上角坐标值,pDatICON是各个图标及其不同显示状态的点阵码值｡反显状态是当图标被 光标滑到或点取时才显现的｡实现鼠标光标,又分两种情况｡一种是单层显示的LCD,只能由程序画出鼠标光标｡但是,当光标移动较快时,画出光标的点阵图形 需要耗用较多的主机资源｡另一种是有双层显示和光标功能的LCD,只需程序控制它的光标移动位置,无需程序画出光标的点阵图形,因而耗用主机资源较少,实 现起来效果较好｡ &lt;/span&gt;&lt;/div&gt; &lt;div  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    两种方案简单､明了,容易实现,都已在实验中得到验证｡并且,后一种方案已在某一仪表系统中得到成功应用｡总体来说,随着嵌入式处理器性能的不断提高,在 嵌入设备中接入鼠标,既可灵活使用,也可减少因接入许多按键而占用的口线数,还能使LCD的图形化显示界面更美观､更人性化｡&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-3389984924641315656?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/3389984924641315656/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=3389984924641315656' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3389984924641315656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/3389984924641315656'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/04/ps2_23.html' title='PS/2鼠标接口的设计与实现'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-8015590205584416010</id><published>2008-04-23T03:18:00.000-07:00</published><updated>2008-04-23T03:33:21.669-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章'/><title type='text'>单片机系统中PS/2键盘驱动程序的设计</title><content type='html'>&lt;span style=";font-family:courier new;font-size:85%;"  &gt;    在单片机系统中,经常使用的键盘都是专用键盘.此类键盘为单独设计制作的,成本高、使用硬件连接线多,且可靠性不高,这一状况在那些要求键盘按键较多的应用系统中更为突出.与此相比,在PC系统中广泛使用PS/2键盘具有价格低、通用可靠,且使用连接线少(仅使用2根信号线)的特点,并可满足多种系统的要求.因此在单片机系统中应用PS/2键盘是一种很好的选择.&lt;br /&gt;文中在介绍PS/2协议和PS/2键盘工作原理与特点的基础上,给出了一个在单片机上实现对PS/2键盘支持的硬件连接与驱动程序设计实现.该&lt;br /&gt;设计实现了在单片机系统中对PS/2标准104键盘按键输入的支持.使用Keil C51开发的驱动程序接口和库函数可以方便地移植到其他单片机或嵌入式系统中.所有程序在Keil uVision2上编译通过,在单片机AT89C51上测试通过.&lt;br /&gt;&lt;br /&gt;1 PS/2协议&lt;br /&gt;目前,PC机广泛采用的PS/2接口为mini-DIN 6pin的连接器,如图1所示.&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_bFpK3lufjY0/SA8NgE6uG8I/AAAAAAAAADo/5w0sK0TpX7k/s1600-h/1_24112114.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp3.blogger.com/_bFpK3lufjY0/SA8NgE6uG8I/AAAAAAAAADo/5w0sK0TpX7k/s320/1_24112114.JPG" alt="" id="BLOGGER_PHOTO_ID_5192383740108479426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;PS/2接口图&lt;br /&gt;PS/2设备有主从之分,主设备采用Female插座,从设备采用Male插头.现在广泛使用的PS/2键盘鼠标均在从设备方式下工作.PS/2接口的时钟&lt;br /&gt;与数据线都是集电极开路结构,必须外接上拉电阻(一般上拉电阻设置在主设备中).主从设备之间数据通信采用双向同步串行方式传输,时钟信号由从设备产生.&lt;br /&gt;&lt;br /&gt;1.1 从设备到主设备的通信&lt;br /&gt;当从设备向主设备发送数据时,首先检查时钟线,以确认时钟线是否为高电平.如果是高电平,从设备就可以开始传输数据;反之,从设备要等待获得总线的控制权,才能开始传输数据.传输的每一帧由11位组成,发送时序及每一位的含义如图2所示.&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_bFpK3lufjY0/SA8NrU6uG9I/AAAAAAAAADw/-EK-pioPpZg/s1600-h/1_24112114.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp0.blogger.com/_bFpK3lufjY0/SA8NrU6uG9I/AAAAAAAAADw/-EK-pioPpZg/s320/1_24112114.JPG" alt="" id="BLOGGER_PHOTO_ID_5192383933382007762" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;从设备到主设备的通信&lt;br /&gt;每一帧数据中开始位总是为0,数据校验采用奇校验方式,停止位始终为1.从设备到主设备通信时,从设备总是在时钟线为高时改变数据线状态,主设备在时钟下降沿读人数据线状态.&lt;br /&gt;&lt;br /&gt;1.2 主设备到从设备的通信&lt;br /&gt;主设备与从设备进行通信时,主设备首先将时钟线和数据线设置为“请求发送”状态,具体方式为:首先下拉时钟线至少100us抑制通信,然后下拉数据线“请求发送”,最后释放时钟线.在此过程中,从设备在不超过10us的间隔内必须检查这个状态,当设备检测到这个状态时,它将开始产生时钟信号.此时数据传输的每一帧由12位构成,其时序和每一位含义如图3所示.&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_bFpK3lufjY0/SA8N2k6uG-I/AAAAAAAAAD4/WBr7jQ-gSe4/s1600-h/1_24112114.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp1.blogger.com/_bFpK3lufjY0/SA8N2k6uG-I/AAAAAAAAAD4/WBr7jQ-gSe4/s320/1_24112114.JPG" alt="" id="BLOGGER_PHOTO_ID_5192384126655536098" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;主设备到从设备的通信&lt;br /&gt;与从设备到主设备通信相比,其每帧数据多了一个ACK位.这是从设备应答接收到字节的应答位,由从设备通过拉低数据线产生,应答位ACK总&lt;br /&gt;是为0.主设备到从设备通信过程中,主设备总是在时钟线为低电平时改变数据线的状态,从设备在时钟上升沿读人数据线状态.&lt;br /&gt;&lt;br /&gt;2 PS/2键盘的编码与命令集&lt;br /&gt;2.1 PS/2键盘的编码&lt;br /&gt;目前,PC机使用的PS/2键盘都默认采用第2套扫描码集.扫描码有两种不同的类型:“通码(make code)”和“断码(break code)”.当一个键被按下或持续按住时,键盘会将该键的通码发送给主机;而当一个键被释放时,键盘会将该键的断码发送给主机.根据键盘按键扫描码的不同,可将按键分为3类:&lt;br /&gt;第1类按键 通码为一个字节,断码为0xF0+通码形式.如A键,其通码为0x1C;断码为0xF0 0x1C.&lt;br /&gt;第2类按键 通码为两字节0xE0+0xXX形式,断码为0xE0+0xF0+0xXX形式.如Right Ctrl键,其通码为0xE0 0x14;断码为0xE0 0xF0 0x14.&lt;br /&gt;第3 类特殊按键 有两个,Print Screen键,其通码为0xE0 0x12 0xE0 0x7C;断码为0xE0 0xF0 0x7C 0xE0 0xF0 0x12.Pause键,其通码为0xE1 0x14 0x77 0xE1 0xF0 0xl4 0xF0 0x77;断码为空.&lt;br /&gt;组合按键扫描码的发送是按照按键发生的次序,如按下面顺序按左Shift十A键:① 按下左Shift键;② 按下A键;③ 释放A键;④ 释放左Shift键,那么计算机上接收到的一串数据为0x12 0x1C 0xF0 0x1C 0xF0 0x12.&lt;br /&gt;在文中的驱动程序设计中,就是根据按键的分类对其分别进行处理.&lt;br /&gt;&lt;br /&gt;2.2 PS/2键盘的命令集&lt;br /&gt;主机可通过向PS/2键盘发送命令对键盘进行设置或者获得键盘的状态等操作.每发送一个字节,主机都会从键盘获得一个应答0xFA(“重发&lt;br /&gt;resend” 和“回应echo”命令例外).驱动程序在键盘初始化过程中所用的指令:0xED,主机在该命令后跟随发送一个参数字节,用于指示键盘上Num Lock,Caps Lock,Scroll Lock Led的状态;0xF3,主机在这条命令后跟随发送一个字节参数定义键盘机打的速率和延时;0xF4,用于当主机发送0xF5禁止键盘后,重新使能键盘.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3 PS/2键盘与单片机的连接电路&lt;/span&gt;&lt;br /&gt;PS/2键盘与AT89C51单片机的连接方式如图4所示.P1.0接PS/2数据线;P3.2(INT0)接PS/2时钟线.因为单片机的P1,P3口内部是带上拉电阻的,所以PS/2的时钟线和数据线可以直接与单片机的P1,P3相连接.&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_bFpK3lufjY0/SA8OA06uG_I/AAAAAAAAAEA/i9f7zRO6Sg8/s1600-h/1_24112114.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp2.blogger.com/_bFpK3lufjY0/SA8OA06uG_I/AAAAAAAAAEA/i9f7zRO6Sg8/s320/1_24112114.JPG" alt="" id="BLOGGER_PHOTO_ID_5192384302749195250" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;4 驱动程序设计&lt;br /&gt;驱动程序的开发使用Keil C51语言以及KeiluVision2编程环境.PS/2 104键盘驱动程序主要任务是实现单片机与键盘间PS/2通信,同时将接收到的按键扫描码转换为该按键的键值KeyVal,提供给系统上层软件使用.&lt;br /&gt;&lt;br /&gt;4.1 单片机与键盘间PS/2通信的程序设计&lt;br /&gt;在PS/2通信过程中,主设备(文中是单片机)是在时钟信号为低时发送和接收数据信号.因为单片机向键盘发送的是指令,需要键盘回应,所以这&lt;br /&gt;部分程序采用查询方式;而单片机接收键盘数据时,数据线上的信号在时钟为低时已经稳定,所以这部分程序采用中断方式,且不需要在程序中加入延时程序.&lt;br /&gt;单片机向PS/2键盘发送数据程序代码为:&lt;br /&gt;void ps2_sentchar(unsigned char sentchar){//ps2主设备向从设备发送数据&lt;br /&gt;unsigned char sentbit_cnt= 0x00;&lt;br /&gt;unsigned char sentchar_chk = 0x00;&lt;br /&gt;EX0=0; //关外部中断0&lt;br /&gt;//发起一个传送,发起始位&lt;br /&gt;PS2_SGN_CLOCK = 0; //将时钟线拉低并保持100 us&lt;br /&gt;delay100us();&lt;br /&gt;PS2_SGN_DATA= 0; //起始位&lt;br /&gt;PS2_SGN_CLOCK = 1;&lt;br /&gt;//发送DATA0-7&lt;br /&gt;for(sentbit_cnt=0;sentbit_cnt&lt; ps2_sgn_data =" sentchar&amp;amp;"&gt;&gt;=1; //待发送数据右移一位&lt;br /&gt;}&lt;br /&gt;//发送校验位&lt;br /&gt;while(PS2_SGN_CLOCK) _nop_(); //等待时钟线变低&lt;br /&gt;switch(sentchar_chk){&lt;br /&gt;case 0:&lt;br /&gt;case 2:&lt;br /&gt;case 4:&lt;br /&gt;case 6:PS2_SGN_DATA =1;break;//奇校验&lt;br /&gt;case 1:&lt;br /&gt;case 3:&lt;br /&gt;case 5:&lt;br /&gt;case 7:PS2_SGN_DATA = 0;break;//奇校验&lt;br /&gt;default;break;&lt;br /&gt;)&lt;br /&gt;while(!PS2_SGN_CLOCK) _nop_(); //等待时钟线变高&lt;br /&gt;while(PS2_SGN_CLOCK) _nop_(); //等待时钟线变低&lt;br /&gt;PS2_SGN_DATA =1;//发送停止位,停止位总为1&lt;br /&gt;while(!PS2_SGN_CLOCK) _nop_(); //等待时钟线变高&lt;br /&gt;while(PS2_SGN_CLOCK) _nop_(); //等待时钟线变低&lt;br /&gt;//接收ACK&lt;br /&gt;//if(PS2_SGN_DATA) error();&lt;br /&gt;//ACK信号由键盘发出,总为低电平&lt;br /&gt;while(!PS2_SGN_CLOCK) _nop_(); //等待时钟线变高&lt;br /&gt;EX0= 1; //开外部中断0&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;单片机由PS/2键盘接收数据程序:外部中断0设置为下降沿触发&lt;br /&gt;void int0() interrupt 0 using 0 {//&lt;br /&gt;EX0=0; //关外部中断0&lt;br /&gt;switch(ps2_revchar_cnt){&lt;br /&gt;case 1:&lt;br /&gt;……&lt;br /&gt;case 8:mcu_revchar&lt;&lt;=1; if(PS2_SGN_DATA) mcu_revchar |= 0x01; ps2_revchar_cnt++;break;&lt;br /&gt;case 0:ps2_revchar_cnt++;break; //开始位,&lt;br /&gt;case 9:ps2_revchar_cnt++;break; //校验位,可添加校验程序&lt;br /&gt;case 10: _nop_();//停止位&lt;br /&gt;ps2_revchar_cnt= 0;&lt;br /&gt;revchar_flag=1;//置接收到数据标识位 break;&lt;br /&gt;default:break;&lt;br /&gt;}&lt;br /&gt;EX0=1;//开外部中断0 } &lt;br /&gt;&lt;br /&gt;4.2 键盘扫描码转换程序设计    &lt;br /&gt;由于键盘扫描码无规律可循,因此由键盘扫描码获得相应按键的键值(字符键为其ASCII值,&lt;br /&gt;控制键如F1,Ctrl等为自定义值),只能通过查表的方式获得.&lt;br /&gt;由于按键的3种类型及部分按键对应着两个键值(如A键的键值根据Caps和Shift键状态有0x41(A)和0x61(a)两种),因此综合考虑查表转换速度和资源消耗,设计中使用4个键盘表:键盘扫描码转换基本集和切换集(kb_plain_map[NR_KEYS]与kb_shift_map [NR_KEYS]);包含E0前缀的键盘扫描码转换基本集和切换集(kbeO_plain_map[NR_KEYS]与kbe0_shiftmap [NR_KEYS]).PS/2 104键盘按键扫描码最大值为0x83,所以设置NR_KEYS为132.所有4个键盘表的定义均为如下形式:KB_MAP[MAKE CODE]=KEYVAL,如果扫描码对应的按键为空(如KB_MAP[0x00]),则定义相应键值为NULL_KEY(0x00).以下是键盘扫描码基本集的部分代码实例: kb_plain_map[NR_KEYS]={…… NULL_KEY;0x2C;0x6B;0x69;0x6F;0x30;0x39; NULL_KEY; //扫描码0x40~0x47 //对应按键空,逗号,K,I,O,0,9,空 //对应键值0x00,',','k','i','o','O','9',0x00…… };     如此设计键盘转换表的另一个好处在于,以后如需扩展支持有ACPI、Windows多媒体按键键盘时,只需要将键表中相应处修改即可,如ACPI Power按键通码为0xE0 0x37,修改kbe0_plain_map[0x37]=KB_ACPI_PWR即可.     特殊按键Pause使用单独程序处理,如果接收到0xE1就转入这段程序.而Print Screen键则将其看作是两个通码分别为0xE0 0x12和0xE0 0x7C 的“虚键”的组合键处理.在驱动程序中设定如下全局变量:led_status记录Scroll Lock Led,Num Lock Led和Caps Lock Led的状态(关为0,开为1);agcs_status记录左右Shift Ctrl Gui Alt状态,相应键按下则对应位为1,释放为0.E0_FLAG接到0xE0置1;E1_FLAG接收到0xE1置1;F0_FLAG接收到0xF0置 1.按键键值通过KeyVal提供上层程序使用.PS/2键盘扫描码键值转换程序ps2_codetrans()流程框架如图5所示. &lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_bFpK3lufjY0/SA8OhU6uHBI/AAAAAAAAAEQ/5Efb-NJdsFc/s1600-h/1_24112114.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp0.blogger.com/_bFpK3lufjY0/SA8OhU6uHBI/AAAAAAAAAEQ/5Efb-NJdsFc/s320/1_24112114.JPG" alt="" id="BLOGGER_PHOTO_ID_5192384861094943762" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;扫描码键值转换程序流程框架  &lt;br /&gt;第1类按键的扫描码键值转换程序代码。&lt;br /&gt;if(F0_FLAG){//接收扫描码为断码 switch(mcu_revchar){//处理控制键&lt;br /&gt;case 0x11:ages_status&amp;amp;=0xF7;break;//左alt释放&lt;br /&gt;case 0x12:ages_status&amp;amp;=0xFE;break;//左shift释放&lt;br /&gt;case 0x14:agcs_status&amp;amp;=0xFD;break;//左ctrl释放&lt;br /&gt;case 0x58;if(led_status&amp;amp;0x04) led_status &amp;amp;= 0x03; //caps lock else led_status |=0x04; ps2_ledchange(); break;&lt;br /&gt;case 0x59: agcs_status &amp;amp;= 0xEF;break;//右shift释放&lt;br /&gt;case 0x77: if(led_status&amp;amp;0x02)led_status&amp;amp;=0x05;//num lock else led_status |=0x02; ps2_ledchange(); break;&lt;br /&gt;case 0x7E:if(led_status&amp;amp;0x01) led_status&amp;amp;=0x06;//scroll lock else led_status |=0x01; ps2_ledchange(); break;&lt;br /&gt;default;break; } F0_FLAG=0;&lt;br /&gt;}&lt;br /&gt;else{//接收扫描码为通码&lt;br /&gt;if(led_status&amp;amp;0x04) caps_flag=1;&lt;br /&gt;else caps_flag = 0;&lt;br /&gt;if(led_status&amp;amp;0x02) num_flag =1;&lt;br /&gt;else num_flag =0;&lt;br /&gt;if(agcs_status&amp;amp;0x11) shift_flag = 1;&lt;br /&gt;else shift_flag=0; //扫描码键值转换&lt;br /&gt;if((caps_flag == shift_flag) || (!num_flag)) KeyVal=kb_plain_map[mcu_revchar];&lt;br /&gt;else KeyVal = kb_shift_map[mcu_revchar];&lt;br /&gt;switch(mcu_revchar)(//处理控制键或状态键&lt;br /&gt;case 0x11:agcs_status|= 0x08;//左alt按下&lt;br /&gt;Case 0x12:agcs_status|= 0x01;//左shift按下&lt;br /&gt;case 0x14:agcs_status|= 0x02;//左ctrl按下&lt;br /&gt;case 0x59:agcs_status|= 0x10;//右shift按下&lt;br /&gt;default:break;&lt;br /&gt;} }    &lt;br /&gt;第2类按键的扫描码键值转换程序与上面相似.注意:在退出该程序段时,对E0_FLAG和F0_FLAG标识清0.Pause键的处理程序,如果接收到 0xE1,置E1_FLAG=1,然后顺次将后续接收到的7个字节数据和Pause的通码后7个字节比较,一致则返回KeyVal=KB_PAUSE;在比较完所有7个字节后清除E1_FLAG标识.&lt;br /&gt;&lt;br /&gt;键盘初始化程序kb_init()流程为:&lt;br /&gt;① 上电后,接收键盘上电自检通过信号0xAA,或者自检出错信号0xFC.单片机接收为0xAA则进入下一步,否则进行出错处理.&lt;br /&gt;② 关LED指示,单片机发送0xED,然后接收键盘回应0xFA,接着发送0x00接收0xFA.&lt;br /&gt;③ 设置机打延时和速率:单片机发送0xF3,接收0xFA,发送0x00(250 ms,2.0 cps),接收0xFA.&lt;br /&gt;④ 检查LED,发送0xED,接收0xFA,发送0x07(开所有LED),接收0xFA.发送0xED,接收0xFA,发送0x00(关LED),接收0xFA.&lt;br /&gt;⑤ 允许键盘,发送0xF4,接收0xFA.键盘LED改变ps2_ledchange()函数流程:发送0xED;接收0xFA;发送led_status;接收0xFA.  5 结语   该驱动程序经Keil uVision2 编译,在AT89C51单片机上运行通过,实现了对PS/2 104键盘的支持,实现了对字符按键大小写切换,Num Lock切换、控制键及组合按键的支持.同时该程序对其他嵌入式或单片机系统中PS/2键盘的应用也有借鉴意义.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-8015590205584416010?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kokoro2000.blogspot.com/feeds/8015590205584416010/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6349370086167910319&amp;postID=8015590205584416010' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/8015590205584416010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/8015590205584416010'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/04/ps2.html' title='单片机系统中PS/2键盘驱动程序的设计'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_bFpK3lufjY0/SA8NgE6uG8I/AAAAAAAAADo/5w0sK0TpX7k/s72-c/1_24112114.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-8822658140278777767</id><published>2008-04-21T10:13:00.000-07:00</published><updated>2008-04-21T10:15:49.211-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章'/><title type='text'>UART中断的例子</title><content type='html'>&lt;p style="font-family: courier new;"&gt;#include "alt_types.h"&lt;br /&gt;#include &lt;string.h&gt;&lt;br /&gt;#include &lt;unistd.h&gt;&lt;br /&gt;#include "system.h"&lt;br /&gt;#include "altera_avalon_uart_regs.h"&lt;br /&gt;#include "altera_avalon_pio_regs.h"&lt;br /&gt;#include "sys/alt_irq.h"&lt;/p&gt;&lt;p style="font-family: courier new;"&gt;&lt;br /&gt;#ifdef UART_BASE&lt;br /&gt;void uart_handle(void *context,alt_u32 interrupt)&lt;br /&gt;{&lt;br /&gt;  unsigned short int data,status;&lt;br /&gt;  status = IORD_ALTERA_AVALON_UART_STATUS(UART_BASE);&lt;br /&gt;  while (!(status &amp;amp; ALTERA_AVALON_UART_STATUS_RRDY_MSK))&lt;br /&gt;    status = IORD_ALTERA_AVALON_UART_STATUS(UART_BASE);&lt;br /&gt;  data =IORD_ALTERA_AVALON_UART_RXDATA(UART_BASE);&lt;br /&gt;  //write status reg;&lt;br /&gt;  status = ALTERA_AVALON_UART_STATUS_TRDY_MSK;&lt;br /&gt;  IOWR_ALTERA_AVALON_UART_STATUS(UART_BASE, status);&lt;br /&gt;  IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE, data);&lt;br /&gt;  IOWR_ALTERA_AVALON_UART_STATUS(UART_BASE, 0);&lt;br /&gt;}&lt;/p&gt;&lt;p style="font-family: courier new;"&gt;void uart_init()&lt;br /&gt;{&lt;br /&gt;  alt_u32 control;&lt;br /&gt;  int divisor;&lt;br /&gt; &lt;br /&gt;  control = ALTERA_AVALON_UART_CONTROL_TRDY_MSK |&lt;br /&gt;  ALTERA_AVALON_UART_CONTROL_RRDY_MSK |&lt;br /&gt;  ALTERA_AVALON_UART_CONTROL_E_MSK;&lt;br /&gt;  IOWR_ALTERA_AVALON_UART_CONTROL(UART_BASE, control);&lt;br /&gt; &lt;br /&gt;  divisor = (int)(50000000/9600+0.5);&lt;br /&gt;  IOWR_ALTERA_AVALON_UART_DIVISOR(UART_BASE, divisor);&lt;/p&gt;&lt;p style="font-family: courier new;"&gt;  if (alt_irq_register(UART_IRQ, NULL, uart_handle))&lt;br /&gt;   {&lt;br /&gt;     IOWR_ALTERA_AVALON_PIO_DATA(PIO_OUT_BASE, 0x0);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;#endif&lt;/p&gt;&lt;span style="font-family: courier new;"&gt;int main(void)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  /* declare var used by uart;*/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  IOWR_ALTERA_AVALON_PIO_DATA(PIO_OUT_BASE, 0x4079);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  uart_init(); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  while(1);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  return 0;  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;}   &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6349370086167910319-8822658140278777767?l=kokoro2000.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/8822658140278777767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6349370086167910319/posts/default/8822658140278777767'/><link rel='alternate' type='text/html' href='http://kokoro2000.blogspot.com/2008/04/uart.html' title='UART中断的例子'/><author><name>~-y朙</name><uri>http://www.blogger.com/profile/12369199113321731977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-6349370086167910319.post-8286894021068590607</id><published>2008-04-13T07:42:00.000-07:00</published><updated>2008-05-27T07:02:10.601-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='技術文章/NIOS2'/><title type='text'>NiosII PIO interrupt (轉貼)</title><content type='html'>&lt;span style="color: rgb(232, 243, 253);font-family:courier new;font-size:85%;"  &gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;PIO（Parallel Input/Output）是SOPCBuilder里面一个最常用的IP之一，而且相对简单，容易上手使用。个人感觉PIO可类比于单片机的GPIO管 脚，用于用户自己定义的外设操作。一般来说，我们在SOPC系统中用PIO主要是因为方便，因为FPGA的管脚越来越多，内部逻辑资源越来越多，所以设计 时几乎不用担心管脚的数目或者逻辑资源是否不够；相比之下单片机的GPIO可能会让用户感到数目不够，有时不够方便。所以在SOPC系统我们可以同时用很 多使用PIO接口的设备。大体来说，这些设备主要分输入和输出两类：&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; 输入类：按钮，自定义键盘等&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; 输出类：LED，LCD定义接口连
