超級任天堂程式設計/初始化教程
顏色 00000000 11100000
在本教程中,我們將介紹如何初始化超級任天堂並將背景更改為美麗的綠色。
- WLA-65816 宏彙編程式。有適用於 Linux 32 位的二進位制檔案
- 一個 SNES 模擬器,例如 bsnes、Zsnes 或Geiger 的 Snes9x 除錯版本,適用於 Windows。
- 一個初始化例程和一個頭檔案。初始化例程顧名思義;它是一段程式碼,用於清除/重置系統值並設定 SNES 以供使用。標頭檔案包含用於 WLA 的彙編指令,這些指令執行定義 ROM 的名稱、大小、向量等操作。
如果您決定將初始化例程和標頭檔案放在單獨的檔案中,則需要告訴彙編器包含它們。
.include "Header.inc"
.include "Snes_Init.asm"
VBlank: ; Needed to satisfy interrupt definition in "header.inc"
RTI
透過將標頭檔案和初始化程式碼放在您的主檔案中,可以跳過此部分。
您可以在 華夏公益教科書上找到 Snes_Init.asm 的 ASM 程式碼,您還可以找到標頭檔案。
雖然對於此專案正常工作並非必需,但需要注意的是,為了使 VBlank 子例程實際被呼叫,您需要按如下所示啟用 NMI 中斷。
lda #$80 ; Set NMI enable bit sta #$4200
在標頭檔案中,標籤“Start”被宣告為重置向量,因此程式將從那裡開始執行。
Start:
大多數演示都會將 SNES 重置到已知狀態。由於模擬器可能以已知狀態啟動,因此對於模擬的 ROM,重置狀態可能沒有必要。但是,重置 SNES 對於演示在實際的 SNES 硬體上執行可能是必需的。
要重置 SNES,我們將許多硬體暫存器設定為零,並將 WRAM 中的所有位元組清零。在這裡,我們使用初始化宏Snes_Init來自檔案“Snes_Init.asm”,來自 SNES Devkit,它為我們執行此操作。
; Initialize the SNES.
Snes_Init
首先,我們將累加器設定為 8 位,以修改 RAM 的單個位元組。我們透過在 CPU 狀態暫存器中設定適當的位來做到這一點。
sep #$20 ; Set the A register to 8-bit.
SNES 重新整理其螢幕以匹配輸出到電視機的訊號,因此瞭解電視機如何更新其影像可以幫助您瞭解 SNES 中某些特殊效果是如何執行的。
電視機使用電子束在螢幕上顯示影像,電子束從左到右掃描螢幕,一次掃描一行,從上到下。此外,電檢視像為隔行掃描,這意味著電視機交替顯示所有偶數掃描線和所有奇數掃描線;每個偶數或奇數掃描線螢幕稱為一個場。NTSC 電視機(在美國和日本使用)每秒顯示大約 30 幀,而 PAL 電視機(在其他地方使用)每秒顯示 25 幀。因此,NTSC 電視機每秒顯示約 60 場,而 PAL 電視機每秒顯示 50 場。
在行與行之間,當電子束從一行最右邊移到下一行最左邊時,電子束將關閉;這被稱為水平消隱或HBlank。某些特殊效果 - 例如最終幻想 VI 飛船的透視效果 - 可以透過在 HBlank 期間更改圖形設定來在 SNES 上執行。
同樣,在場與場之間,當電子束從螢幕底部移到螢幕頂部時,電子束將關閉;這被稱為垂直消隱或VBlank。如果您在電子束開啟時更新螢幕,則顯示給使用者的結果是不可預測的;它們可能會出現剪下或其他偽像。因此,您希望在 HBlank 或 VBlank 期間對螢幕進行所有修改。由於 VBlank 比 HBlank 長得多,並且覆蓋整個螢幕,因此大多數更新應在 VBlank 期間完成。VBlank 每場發生一次,或在 NTSC 機器上每秒約 60 次,在 PAL 機器上每秒約 50 次。
有兩種方法可以確保您的程式碼在 VBlank 期間執行
- 等待 VBlank 非遮蔽中斷 (NMI)。
- 透過設定螢幕顯示暫存器 ($2100) 的第八位來關閉螢幕。
在這裡,我們透過以下程式碼關閉螢幕來強制 VBlank
lda #%10000000 ; Force VBlank by turning off the screen.
sta $2100
SNES 以以下格式儲存 16 位顏色
- 高位元組:0bbbbbgg
- 低位元組:gggrrrrr
我們將使用的顏色是00000000 11100000(0 藍色,7 綠色,0 紅色) - 深綠色。我們使用顏色資料暫存器 ($2122) 設定螢幕的背景顏色
lda #%11100000 ; Load the low byte of the green color. sta $2122 lda #%00000000 ; Load the high byte of the green color. sta $2122
我們透過再次使用螢幕顯示暫存器 ($2100) 開啟螢幕並將亮度設定為 15 來結束 VBlank。
lda #%00001111 ; End VBlank, setting brightness to 15 (100%). sta $2100
與許多計算機程式不同,SNES 程式並非真正設計為結束。SNES 遊戲旨在一直執行,直到使用者關閉系統或按下重置鍵。然而,在我們的例子中,SNES 已完成我們希望它執行的所有操作,現在我們希望它靜止不動,不再改變任何東西。我們透過一個無限迴圈來實現這一點。
; Loop forever.
Forever:
jmp Forever
如果我們沒有這個迴圈,SNES 將開始執行任何碰巧位於我們程式後面的程式碼或資料,這可能會使 SNES 做一些我們不想做的事情。
或者,我們也可以使用“STP”命令。此命令會使 SNES 的 CPU 停滯,直到控制檯重置。但是,無限迴圈是一個很好的做法,因為我們最終會需要一個主程式迴圈,而這將變成主程式迴圈。
一旦我們在一個檔案中獲得了我們的程式 - 我們稱之為“Greenspace.asm" -- 我們希望將其組裝成一個 ROM 映象,以便我們可以在模擬器中執行它。首先,我們執行 WLA 65816 彙編器將彙編檔案轉換為目標檔案。
wla-65816 -o Greenspace.obj Greenspace.asm
這應該會建立目標檔案 "Greenspace.obj".
然後,我們需要將目標檔案連結到 ROM 中。WLA 連結器需要一個連結檔案,其中列出了要連結的檔案。我們將建立一個名為 "Greenspace.link" 的檔案,其內容如下
[objects] Greenspace.obj
然後,我們只需要執行 WLA 連結器
wlalink Greenspace.link Greenspace.smc
這應該會建立 ROM 映象 "Greenspace.smc", 然後我們可以在模擬器中執行它。
為了使編譯和連結步驟更容易重複執行——就像我們在編輯和測試之間交替進行時可能想要做的那樣——我們可以將命令放在 shell 指令碼 中,"Greenspace.bat" 在 DOS/Windows 中,或者 "Greenspace.sh" 用於 UNIX。
wla-65816 -o Greenspace.obj Greenspace.asm wlalink Greenspace.link Greenspace.smc
如果你使用 UNIX,你需要在檔案的首行新增#!/bin/bash。在 Windows 下,最好在首行新增@echo off。
或者,如果您在基於 UNIX 的平臺上,您可以建立一個 makefile 並使用 make 工具。為此,建立一個名為 "makefile".
Greenspace.smc: Greenspace.asm Greenspace.link
wla-65816 -o Greenspace.obj Greenspace.asm
wlalink Greenspace.link Greenspace.smc
在建立此檔案後,只需使用 "make" 命令,然後 "Greenspace.smc" 將被建立。
完整的原始碼
[edit | edit source] ; SNES Initialization Tutorial code
; This code is in the public domain.
.include "Header.inc"
.include "Snes_Init.asm"
; Needed to satisfy interrupt definition in "Header.inc".
VBlank:
RTI
.bank 0
.section "MainCode"
Start:
; Initialize the SNES.
Snes_Init
; Set the background color to green.
sep #$20 ; Set the A register to 8-bit.
lda #%10000000 ; Force VBlank by turning off the screen.
sta $2100
lda #%11100000 ; Load the low byte of the green color.
sta $2122
lda #%00000000 ; Load the high byte of the green color.
sta $2122
lda #%00001111 ; End VBlank, setting brightness to 15 (100%).
sta $2100
; Loop forever.
Forever:
jmp Forever
.ends
有問題嗎?看到預設黑色嗎?在 討論頁面 上告訴我們。