NES專題——PPU工作原理

目錄

摘要

一、2C02概述

二、PPU內存映射

三、PPU寄存器

四、調色板

五、圖案表

六、名稱表/屬性表

七、精靈

八、滾動

九、電視標準

十、參考資料


摘要

本文介紹了NES遊戲機上PPU的工作原理以及背景和精靈圖像的顯示方法,本文參考《Nintendo Entertainment System Documentation(任天堂娛樂系統文檔)》,如需對PPU進一步的瞭解可以查閱該文檔。在查資料的時候也發現了一篇寫的很好的文章,我附在了文章最後的參考資料裏。

 

一、2C02概述

在6502的基礎上,理光也提供了2C02作爲PPU(Picture Processing Unit 圖形處理單元),相當於現在的顯卡。PPU的寄存器主要位於CPU內存的I/O寄存器部分,地址爲$2000-$2007和$4014。另外,還有一些特殊的寄存器用於屏幕滾動。(“$”在文中代表16進制的意思)。

 

二、PPU內存映射

PPU有自己的內存,稱爲VRAM(Video RAM)。與CPU一樣,PPU也可以尋址64 KB的內存,儘管它只有16 KB的物理RAM。PPU的內存映射如下圖所示。左邊部分顯示了一個簡化的版本,這是由右邊部分詳細說明的。由於物理地址空間和邏輯地址空間的不同,任何超過$3FFF的地址都被包裝起來,使邏輯內存位置$4000-SFFFF實際上成爲位置$0000-$3FFF的鏡像。

可以通過使用CPU內存中的I/O寄存器$2006和$2007來完成對PPU內存的讀寫。這通常是在幀末的V-Blank期間完成的,因爲它影響在繪製屏幕時使用的地址,因此會破壞顯示的內容。然而,這個效果可以用來產生分割屏幕效果。

由於PPU內存使用16位地址,但是I/O寄存器只有8位,所以需要兩次寫入$2006來設置所需的地址。數據可以從$2007讀取或寫入。每次寫入到$2007之後,地址將按照$2000的第2位的要求增加1或32。$2007的第一次讀取是無效的,數據將在下一次讀取時被緩衝並返回。這不適用於調色板。

PPU還有一個單獨的256字節的內存區域,即Sprite RAM (Sprite RAM),用於存儲Sprite(精靈)屬性。精靈本身可以在模式表中找到。(精靈指的是遊戲中的角色或者怪物)。

PPU內存映射圖

 

三、PPU寄存器

CPU和其他設備之間的通信通過內存映射I/0寄存器進行。PPU使用的寄存器位於主存中,價格爲$2000-$2007,另一個寄存器用於直接內存訪問,地址爲$4014。請記住,位置$2000-$2007在$2008-$3FFF區域中每8個字節鏡像一次。CPU可以通過寫入$2000和$2001來控制PPU的動作,分別稱爲PPU控制寄存器1和PPU控制寄存器2,這兩個寄存器是隻寫的。$2000的第7位可以用來禁用NMIs。請記住,這種類型的中斷是在出現V-Blank時產生的,並且不受狀態寄存器的中斷禁用標誌的影響。由於NES同時支持8x8和8x16的精靈,所以清除這個位將防止NMI在V-Blank上發生,設置$2000的第5位將切換到8x16的精靈。每次I/O發生後,PPU內存中要讀寫的下一個地址將增加。通過設置$2000的第2位的值來調整要增加的值。如果該位是清除的,地址增加1(水平),否則增加32(垂直)。使用$2001,背景可以通過清除第3位隱藏,同樣,精靈可以通過清除第4位隱藏。

PPU狀態寄存器位於$2002並且是隻讀的,寄存器被PPU用來向CPU報告它的狀態。程序將頻繁地讓CPU去讀取這個地址以確定PPU的狀態。第7位由PPU設置,以指示V-Blank正在發生。第6位和第7位與精靈有關,將在後面介紹。第4位表示PPU是否願意接受對VRAM的寫操作,如果該位清除,則寫操作會被忽略。當從$2002讀取數據時,第7位被重置爲0,就像$2005和$2006一樣。

直接內存訪問(DMA)

在設備之間傳輸大量數據時,通過處理器傳輸數據是低效的。例如,將數據從CPU內存傳輸到精靈內存需要以下步驟:

(1)將所需的SPR-RAM地址加載到CPU。

(2)寫入所需的SPR-RAM地址到$2003。

(3)加載字節到CPU。

(4)將字節寫入$2004。

當填充精靈內存的內容時,這項技術需要重複256次。直接內存訪問(DMA)是一種允許更有效地將數據從CPU內存複製到精靈內存的技術。使用DMA,整個精靈內存可以通過使用一條指令來填充,寫入到$4014。CPU內存中的起始地址由操作數指定,寫操作數乘以$100。從這個地址開始的256字節被直接複製到sprite內存中,而不需要進一步的CPU介入。當DMA發生時,內存總線正在使用中,從而阻止CPU訪問內存,從而阻止它訪問更多的指令。這被稱爲週期竊取,CPU必須等待DMA傳輸完成。在NES上,DMA相當於512個週期(大約4.5掃描行),之後CPU可以恢復。這比通過CPU手動複製要少得多。

 

四、調色板

NES有一個包含52種顏色的調色板,儘管實際上有64個區域。然而,並不是所有這些都可以在給定的時間顯示。NES使用兩個調色板,每個有16個條目,圖像調色板($3F00-$3F0F)和精靈調色板($3F10-$3F1F)。圖像調色板顯示當前背景塊可用的顏色。精靈調色板顯示精靈當前可用的顏色。這些調色板不存儲實際的顏色值,而是系統調色板中的顏色索引。由於只需要64個唯一值,所以可以忽略第6和第7位。

調色板條目$3F00是背景色,用於透明。使用鏡像使調色板中的每四個字節是$3F00的一個副本。因此,$3F04、$3F08 $3FOC、$3F10、$3F14、$3F18和$3F1C只是$3F00的副本。每個調色板的顏色是13,而不是16。因此,在任何時候,屏幕上的顏色總數是52種顏色中的25種。兩個調色板也鏡像到$3F20-$3FFF。

 

五、圖案表

NES有兩個圖案表,分別爲$0000和$1000。圖案表存儲可以在屏幕上繪製的8x8像素的塊。許多遊戲將圖案表存儲在磁帶的CHR-ROM中,但是,沒有CHR-ROM的遊戲將使用RAM作爲圖案表,並在執行期間填充它們。圖案表存儲標識該像素使用的圖像或精靈調色板索引所需的4位數字中最不重要的兩位,比如00b是調色板條目0,01b是1,10b是2,11b是3。

圖案表

上圖顯示了圖案表的工作方式。字符“A”是最後的結果,顯示在底部。該字符是通過從左上角和右上角各取一個比特來構建一個像素,從而生成一個2比特的顏色。顏色的其他兩位來自屬性表。顯示的顏色不是真正的NES調色板值。

 

六、名稱表/屬性表

名稱表本質上是一個編號矩陣,指向存儲在圖案表中的編號。名稱表是32x30塊,由於每個塊是8x8像素,所以整個名稱表是256x240像素。

每個名稱表都有一個相關的屬性表。屬性表包含顏色塊的上兩位。屬性表中的每個字節表示4x4組塊,因此屬性表是這些組的8x8表。每個4x4組進一步劃分爲4個2x2的正方形,如下圖所示。8x8塊的編號是$0-$F。字節的佈局爲33221100,其中每兩位指定對應正方形的最有效的兩個顏色位。

4X4編號組佈局

NES只有2KB來存儲名稱表和屬性表,允許它分別存儲兩個。然而,它最多可以解決其中的四個問題。鏡像是用來實現這一點的。以下描述了四種鏡像類型,它們使用邏輯名稱表的縮寫(可以尋址的):L1($2000)、L2($2400)、L3($2800)和L4 ($2C00)。

(1)水平鏡像將L1和L2映射到第一個物理名稱表,將L3和L4映射到第二個物理名稱表,如下圖所示。

水平鏡像

(2)垂直鏡像將L1和L3映射到第一個物理名稱表,將L2和L4映射到第二個物理名稱表,如下圖所示。

垂直鏡像

 (3)單屏幕鏡像將所有四個邏輯名稱表指向同一個物理名稱表,如下圖所示。

單屏幕鏡像

(4)四屏鏡像在磁帶本身中使用額外的2KB RAM,允許邏輯名稱表映射到各個獨立的物理名稱表,如下圖所示。

四屏幕鏡像

 

 

七、精靈

精靈是要畫在屏幕上的角色。精靈可以是8x8像素,也可以是8x16像素。大多數角色是由多個精靈組成的。精靈圖案數據存儲在模式表中,而精靈屬性存儲在ram中。最多有64個精靈,每個精靈在ram中使用4個字節。字節的工作方式如下:

字節0:存儲精靈的y座標。

字節1:圖案表中精靈的索引號。

字節3:存儲精靈x座標。

字節2:存儲精靈的屬性表。

(1)Bits 0 -1——顏色的最重要的兩位。

(2)Bit 5——表示這個精靈是否比背景擁有顯示的優先權。

(3)Bit 6——表示是否水平翻轉精靈。

(4)Bit 7——表示是否垂直翻轉精靈。

8x16精靈根據索引號使用不同的模式表。如果索引號是偶數,則精靈數據位於第一個模式表中的$0000。否則,它在第二個模式表中爲$1000。

可以一次讀取或寫入一個精靈,方法是先將所需的地址寫入$2003,然後讀取或寫入$2004。或者,整個SPR-RAM可以通過一個DMA操作在$4014處寫入。

精靈的優先級是基於他們在SPR-RAM中的位置。第一個精靈稱爲sprite 0,具有更高的優先級。在每一行,系統會計算出哪些精靈在哪一行,然後畫出它們,最低優先級優先,以確保高優先級的精靈畫在最上面。每個掃描線只允許8個精靈,系統通過設置$2002的I/O寄存器第5位來指示何時達到這個數字。

用於滾動的一個常用技術涉及到確定sprite 0是否重疊了一個不透明的背景像素。如果系統正在繪製sprite 0,並且其中任何不透明的像素與不透明的背景像素處於相同的位置,那麼系統將在$2002的第6位中設置sprite 0 hit標誌。因此,如果背景塊只包含透明像素,那麼sprite 0 hit標誌將不會被設置。下圖顯示了sprite 0檢測。左邊的圖像顯示背景,中間的圖像顯示精靈,右邊的圖像顯示兩者的合成。顏色0表示透明度,圈內的像素表示設置了sprite 0 hit標誌的位置。

sprite 0 檢測圖

精靈通常比單個字符大,因此由多個字符組合而成。例如,如下圖顯示了馬里奧角色是如何由8個獨立的8x8字符組成的。

精靈的構建

 

八、滾動

背景可以水平或垂直滾動,滾動使用單獨的名稱表。在任何給定的時間,屏幕上的背景要麼直接取自一個名稱表,要麼是兩個名稱表的組合。如下面兩張圖所示,第一張圖顯示了兩個名稱表的內容(另外兩個當然是鏡像),第二張圖顯示了屏幕上顯示的合成圖像,包括精靈。

”超級瑪麗”中的水平滾動
合成圖像

最後的圖像從第一個名稱表開始,一直延伸到第二個名稱表。第一張圖顯示了兩個名稱表之間的灰線分隔。兩條藍線表示屏幕上顯示的區域。在屏幕的左邊是已經顯示的部分,現在已經從屏幕上滾動了。在屏幕的右側是系統當前正在用前面的名稱表填充名稱的地方,當“馬里奧”繼續前進時,名稱表將顯示在屏幕上。正如被切成兩半的雲所展示的,並不是所有的區域都被系統填滿了。有些遊戲只允許在一個方向上移動,而有些則允許在兩個方向上滾動。這是任天堂描述如下:

“PPU一次只能顯示960個字符,但它實際存儲的字符是這個數字的兩倍。在單向滾動中,新字符不斷地替換滾動後面的舊字符。這就是爲什麼在像《超級馬里奧兄弟》這樣的遊戲中,屏幕只能向一個方向滾動。然而,在《大都會》中,玩家可以在兩個方向上滾動,並不斷地向滾動方向添加新角色。”

水平和垂直滾動的大致情況如下圖所示,這裏顯示的名稱表A是由$2000的0-1位指定的,B是後面的名稱表(這取決於鏡像技術)。這不適用於允許同時水平和垂直滾動的遊戲,背景圖像將跨越名稱表。

水平和垂直滾動

 

用於背景的名稱表

 

滾動的工作方式在[8]中進行了描述,並在這裏進行了總結。系統維護一個16位的VRAM地址寄存器,其值設置爲$2006。寄存器的佈局如下:

Bits 0-11——將名稱表中的地址存儲爲$2000的偏移量。BIts 0-4是x-scroll(指示X方向上的滾動),並隨着線條的繪製而遞增。當這個值從31增加時,它將清0並交換Bit 10。Bits 5-9是y-scroll(指示Y方向上的滾動)並在行尾遞增。當從29開始增加時,它將清0並交換Bit 11。如果寫入到$2007的值設置爲大於29,那麼當它達到31時,它將清0,但是第11位不受影響。

Bits 12-14:位是平鋪y偏移量。

由於x-scroll和y-scroll表示平鋪數字,因此允許32個平鋪在屏幕上(256個像素),30個平鋪在屏幕上(240個像素),總共960個平鋪。

還有第二個臨時VRAM地址寄存器,也是16位長。最後是3位平鋪的x偏移量。這些數據通過寫入寄存器和繪製幀來更新。

 

九、電視標準

NES連接電視向用戶顯示遊戲。NTSC(國家電視標準委員會)是北美、南美大部分地區和亞洲部分地區使用的標準。PAL(相位交替線)是歐洲、亞洲大部、非洲和大洋洲所採用的標準。下表顯示了NES的NTSC版本和PAL版本的區別。

NTSC與PAL NES系統的比較。
  NTSC PAL
幀/秒 60 50
時間/幀(毫秒) 16.67 20
掃描線/幀(其中爲V-Blank) 262(20) 312(70)
CPU週期/掃描線 113.33 106.56
分辨率 256x224 256x240
CPU速度 1.79MHz 1.66MHz

電視屏幕上顯示的圖像是由高速電子流在屏幕上從左到右移動,畫出每個像素。一行像素作爲掃描線。在掃描線的末端,電子束必須移動到下一行並返回到左邊才能繼續。完成此操作所需的時間稱爲水平空白週期(H-Blank)

在繪製屏幕一次後,電子束必須回到左上角,準備開始下一幀。執行此操作所需的時間稱爲垂直空白週期(V-Blank)。當進入V-Blank週期時,PPU通過設置I/0寄存器$2002的第7位來表明這一點。這個位將在CPU下一次讀取$2002時重置。

在NES的NTSC版本中,屏幕上有240行掃描線(儘管頂部和底部的8行被切斷了),它需要額外的3行掃描線的CPU週期輸入V-Blank。在繪製下一幀之前,V-Blank週期又需要20行掃描線。

 

十、參考資料

文章:

《說說小霸王學習機的PPU》http://blog.sina.com.cn/s/blog_50658d150102xc4b.html

《Nintendo Entertainment System Documentation(任天堂娛樂系統文檔)》

資料鏈接:

https://pan.baidu.com/s/1QhbK6ADAHqe1mHkKGALH6A  提取碼:rr69

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章