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