跳转到内容

超级任天堂编程/初始化教程

来自维基教科书,开放世界开放书籍

颜色 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]
华夏公益教科书