周三下午三點,我在 MartyPC 的調試控制臺里盯著那行輸出,心里清楚:有些秘密藏不住了。盡管這個模擬器因為超高的周期精度收獲不少好評,讓它跑起 Area 5150 的“Wibble”和“Lake”兩個場景時,其實一直都帶著一把專屬的“后門鑰匙”。“Wibble”是查理·卓別林、那個綠家伙和大象同臺的畫面,“Lake”則是演示最后的片尾,兼具水波特效和 PCM 音頻播放。說白了,我作弊了。
這么說可能有點嚴厲。針對性修補在模擬器圈子里一點兒也不新鮮。翻看歷史,許多知名模擬器都靠游戲專屬補丁來繞過 bug 或精度不足,好讓特定游戲跑起來。等模擬器精度慢慢提升、研究者對系統內部機制挖得更深,這類補丁才逐步退出舞臺。拿 DOSBOX-X 的代碼倉庫搜一下“hack”這個關鍵詞,跳出來的結果夠你翻上半天——我并不是一個人。
![]()
替自己分辨一句:MartyPC 對特效本身的執行,從一開始就是周期精確的;真正的難題在于,怎么讓特效開始。這篇文章就攤開來講,難在哪兒,以及我最后怎么修掉了那個 hack。
![]()
IBM 的 CGA(彩色圖形適配器)實在是個被束縛住手腳的設備。缺乏垂直同步中斷讓它生來就不宜用于游戲。當年其他計算機系統和絕大多數游戲機,都會提供某種幀級別或多幀級別的中斷,由此告訴運行中的程序,顯示器的電子束當前處于屏幕的哪個已知位置。這個信息能幫程序避免在顯存正被掃描輸出時進行讀寫,否則輕則畫面閃爍,重則出現 CGA 上最扎眼的雪狀噪點。
雪狀噪點對 Area 5150 而言,幾乎是貫穿全場的主敵。該演示絕大多數效果運行在 80 列文本模式下,而這一模式下雪狀噪點的威脅始終高懸。于是,每個效果都必須小心選擇訪問顯存的時機,限定在水平和垂直消隱期內。另一些效果還要精確調整每個掃描行的顯存起始地址。那么,在沒有垂直同步中斷的情況下,程序要如何知道當前掃描位置?最直接的辦法,就是輪詢 CGA 的 03DAh 端口狀態寄存器。
![]()
這個狀態寄存器里藏著兩個關鍵位。第 3 比特指明是否處于垂直消隱期。第 0 比特則是 CRTC(陰極射線管控制器)的“顯示使能”信號的反相值——當該位被置 1,意味著電子束正處在屏幕的可見區域之外的某處。Area 5150 就是通過對這兩比特持續的、精打細算的輪詢,才能在幾乎沒有中斷配合的硬件上,卡準每一個消隱窗口,實現那些看似不可能的效果。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.