一天后,橫井俊平終於看到了讓他牽掛了一晚上的答案。看到這個答案的時候,他差點要給自己一拳,因為這個答案點居然是最基礎的理論。
“堆棧!?”
不錯,王秋陽給出的答案就是堆棧。
所謂堆棧,就是在單片機應用中,有一個特殊的存儲區。它的主要功能是暫時存放數據和地址,通常用來保護斷點和現場。這個存儲區,就是堆棧。
但堆和棧,又有些許的不同。
堆,是隊列優先,先進先出(FIFO―first in first out)。
棧,是先進後出(FILO―First-In/Last-Out)。
6502堆棧$100--$1FF最多隻能存放127個雙字節,所以JSR最大連續的轉入深度為127層。如果還有其它數據入棧,子程序轉入深度還要減少。所以在設計複雜的程序時,堆棧是會出現溢出的。堆棧溢出,意味著主機會死機。
死機代表什麽?
橫井俊平終於意識到了關鍵,因為死機不代表結束。對普通人來說死機意味著重啟,而在黑客的手上死機意味著BUG就要出來了。
果然,王秋陽的回復中,依據堆和棧的特點,做出了不一樣的文章。
堆,因為是先進先出,理論上是由電腦自行運算。
棧,由於是先進後出,因此可以人為控制其運算。
說形象一點,堆就像地鐵,乘客隻要買票,上車後可以萬事不管,輕輕松松的坐車到站。但是地鐵隻管到站,不會送你到家門口。
而棧,則更像私家車。私家車需要自己駕駛,不像乘地鐵那樣輕松。但是它的自由度更大,想去哪兒就去哪兒,想什麽時候出發隨心所欲。
一個棧,在沒有數據進棧時堆棧指針S=$FF。
每當有一個數據進棧S-1→S。
每當有一個數據出時棧S+1→S。
當執行JSR指令時,CPU把下一條指令地址-1,也就是兩個字節自動入棧,即是程序的返回地址-1自動入棧,然後轉入到子程序中執行。
當遇到RTS時彈出棧頂2個字節,作為程序的返回地址,並轉到下一條指令中執行。而這次執行,是可以人為控制的。
也就是說讓堆自主運算,然後人為的控制棧的數據流動,這就能夠讓6502芯片自發的完成定時器的效果,造成和留白一樣的假死機,也就是花屏。
而且這個花屏的顏色,將不再是黑色,因為它已經BUG過了。加之棧現在避開的電腦的自主操作,可以這次花屏可以人為的“默認”它顯示灰階。
“還有這種操作?”
看到這裡,橫井俊平直感慨,為什麽自己的思維總跟不上節奏?再看之前的同顯五十二色匯編語言,他甚至懷疑這篇稿件是未來的某個人寫出來的才對。
思路被打通之後,後面的內容,橫井俊平看得就輕松了許多,但同樣很扣人心弦。
因為後面分析的,就是如何利用PPU增加發色數。
現行PPU和6502.7芯片一樣,是由理光設計,十六進製支持既定4x16色號調色版的型號。
電腦的畫面製作,是由PPU擬定原始色號,也就是物理運算芯片。之後由GPU負責運算,顯示,最後CPU負責全程調控。可以說PPU是發色的基礎,它的發色原理來源於芯片上的寄存器。
寄存器本身分為兩個概念,一個是物理概念,也就是寄存真實的顏色,比如紅,綠,藍這樣的顏色。另一個概念,就是運算概念,PPU把這些顏色以數據的形式傳送給電腦,再由GPU通過顯卡把數據傳送到屏幕上。當然,FC沒有單獨顯卡,GPU是集成於主板上的。
其中的物理概念,重點就在於寄存器對發色的選定。
電腦的三源色是紅,綠,藍。6502的發色原理是構建兩條垂直伸展的軸線,分別是X和Y,從左上角向右方和下方延展。原色紅居於正上方,藍居於左下角方,綠居於右下方。
由於6502認定屏幕的上和下,左和右是互通的,因此發色的區域左邊自形成的白色起始,漸進到灰色,然後是從紫到紅,向右漸變為青色,再到綠色,最後是黑色。
自上而下,則是從紅色漸變到橙色,再到黃色為止。而座標的斜方向,就是漸變的一些靠近主色的近色。PPU寄存器要做的,就是選定一個發色范圍,同時將需要的顏色以數據的形式貯存下來。
如果以後需要某種顏色,PPU就能夠提交數據,迅速以相應的座標記憶將三原色搭配出的色彩毫無差錯的構建出來。這也是電腦讓人類無法企及的超強運算能力,哪怕隻是八位處理性能的6502。
試問,就是一位畫家,他能夠保證自己每次調配出來的色號完全一樣嗎?肯定不能,但是電腦就可以。
和6502協同運算的PPU,座標記憶就是達到四乘以十六的一個區間,在寄存器中貯存下來。這些數據,就是電腦的調色板,即物理運算;而這些能夠隨時轉化為顏色的座標數據,就是色號,即數據運算。
6502要增加PPU上的遊戲色號,這個堆棧就要聯系到卡帶上的臨時貯存器。
任天堂的卡帶上有四個重要的組成部分,分別是ROM-chr,ROM-prg,MMC芯片, 還有RAM。當然還有電池,密碼鎖等和程序關系不大的配件。
其中,ROM-chr用來貯存遊戲的圖文,ROM-prg貯存程序。
而在遊戲過程中,運算都是在RAM中進行的。RAM全稱為Random- Memory,代表遊戲內存。它的功能是暫時存儲數據供CPU調取。
由於卡帶的讀取速度跟不上6502的處理速度,因此所有的程序運行都是先從卡帶讀取數據並加載到內存中,再寫入CPU內部的高速緩存進行處理。
人為增加發色數的過程,將在這裡完成最後的步驟。
RAM在待機狀態下為空,也就是說,RAM負責在遊戲運行時貯存臨時數據。從某種意義上來說,RAM和堆棧的作用很相似,隻是它的容量非常之小,一般隻有20Kb(1Kb等於8字節)。
這個就是臨時貯存器。在“定時器”的原理下,色號能存在兩個。它能夠把灰階20像黑色那樣,指定為花屏底色,強製電腦顯示出來,使它成為可用色號。
因為CPU顯示出默認灰階,成為了同顯發色色號。因此人為的再使用灰階30,就能夠在黑色之外再增加一款發色數,而且本身並不佔用到任何內存。
如此一來,即便在沒有MMC芯片的支持下,發色數也增加到了十四種。即黑色,灰階,以及十二種彩色!
看到這裡,橫井俊平忍不住感慨道:“科樂美為了研發MMC芯片,花了兩年時間,增加了一款發色數。而這套匯編才用了兩天,真是讓人難以置信!”