跳轉到內容

超級任天堂程式設計/初始化教程

來自華夏公益教科書,開放世界開放書籍

顏色 00000000 11100000

在本教程中,我們將介紹如何初始化超級任天堂並將背景更改為美麗的綠色。

所需工具

[編輯 | 編輯原始碼]

彙編指令

[編輯 | 編輯原始碼]

如果您決定將初始化例程和標頭檔案放在單獨的檔案中,則需要告訴彙編器包含它們。

.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

[編輯 | 編輯原始碼]

大多數演示都會將 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.

步驟 1:強制 VBlank

[編輯 | 編輯原始碼]

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

步驟 2:設定背景顏色

[編輯 | 編輯原始碼]

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

步驟 3:結束 VBlank

[編輯 | 編輯原始碼]

我們透過再次使用螢幕顯示暫存器 ($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 停滯,直到控制檯重置。但是,無限迴圈是一個很好的做法,因為我們最終會需要一個主程式迴圈,而這將變成主程式迴圈。

組裝 ROM

[編輯 | 編輯原始碼]

一旦我們在一個檔案中獲得了我們的程式 - 我們稱之為“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

有問題嗎?看到預設黑色嗎?在 討論頁面 上告訴我們。

生成的 ROM 檔案

[edit | edit source]
華夏公益教科書