NESASM教程——第六天——跳转和按键处理

【读取按键】

我们假设你要读取的是一个普通的方形NES手柄,而不是一些其他乱七八糟的东西。为了知道一个按键是否按下,你一次一键地读取0x4016(手柄1)或0x4017(手柄2)。如果按键按下,右边的bit0将被置位(1)。你用1同它相“与”,若结果不为0则跳转。在你读取任何内容之前,你需要先复位手柄(选通)。

【选通/复位】

为了选通/复位手柄,我们写入一个1然后一个0到0x4016(手柄1)或0x4017(手柄2)。可以这么搞:

lda #$01
sta $4016
lda #$00
sta $4016

对,就这样!之后可以真正读取手柄信息。

【读取顺序】

在对0x4016或0x4017进行的的每个读取操作,你获得了不同按键的状态,这些被读出按键的顺序为:

读取序号  |   对应按键

1.    A

2.    B

3.    SELECT

4.    START

5.    UP

6.    DOWN

7.    LEFT

8.    RIGHT

那么在我们搞些事情之前先学习一些条件和跳转指令怎么样?

【条件跳转】

我们在大多数指令中设置了一些特定“条件”,他们是:

EQ——EQual-Zero, 等于0

NE——Not Equal,不等于0

LT——Less Than,小于0

GT——Greater Than, 大于0

PL——Plus,正数

MI——Minus,负数

CC——Carry Clear,进位标志为0

CS——Carry Set,进位标志为1

VC——oVerflow Clear,溢出标志为0

VS——oVerflow Set, 溢出标志为1

这些条件会被大多数指令设置,甚至包括数据载入。所有这些条件都有一个分支指令。在条件码前加上“B”就构成了条件跳转指令,例如:

;假设有个标签叫做Loopto
beq Loopto;跳到Loopto如果上个比较结果为相等或者上条指令结果为0
bpl Loopto;跳到Loopto如果上次结果bit7为0
bmi Loopto;你懂的

我希望你已经发现规律了。我相信只有NE和EQ条件能被一个非比较指令影响。

以防万一你不知道,偷偷告诉你,一个label(标签)就是一个名称后面跟上冒号,例如

Loopto:
aslkdfj:
Hello_a:

我希望你懂了。记住:标签很好玩。

【读取按键的一个小栗子】

说够了。上代码:

	lda #$01    ; |
	sta $4016   ;  \
	lda #$00    ;   - 设置手柄用来读
	sta $4016   ; _/

	lda $4016  ; 读取按键A
	and #1     ; 判断是否按下
	bne WasDown  ; 按下就走
	; 我不确定为什么是个BNE,但就是这样,所以就用吧!

	lda $4016  ; 读取按键B
	lda $4016  ; 读取按键SELECT
	lda $4016  ; 读取按键START
	and #1     ; 看看是否按下了?
	bne StartDown  ; 按下了,走起~

	lda $4016  ; UP
	lda $4016  ; DOWN
	lda $4016  ; LEFT
	lda $4016  ; RIGHT

	jmp NothingDown  ; 滚远点

StartDown:
	; 开始了开始了

WasDown:
	; AAAAAAAAAAAAAAAA

NothingDown:
	; 啥都不干

希望你不认为这太难。

个人认为GBA是更容易编程的。所以对我而言,NES程序需要更多学习来搞明白。

【复习今天内容】

首先我想提一点,你可能知道我的GBA 汇编系列教程了,或许你也知道我的x86(DOS)汇编教程?在三门汇编语言中穿梭有时让人抓狂,所以如果你看到一些奇怪的或者错误,让我知道就行。谢谢。

按键检测不那么激情澎湃,但我可以告诉你后面更精彩。。。

时间: 2024-08-18 05:10:15

NESASM教程——第六天——跳转和按键处理的相关文章

NESASM教程总述

本教程是关于使用NESASM汇编器为任天堂娱乐系统(NES, Nintendo Entertainment System)编程的.该教程由浅入深,简化了NES汇编学习过程.在进一步尝试前你几乎必须了解另一种汇编语言,因为本文假设你(哪怕一丁点)基本汇编常识是具备的.例如了解GBA或者Intel x86汇编将对理解基础有很大帮助.祝你在学习NES汇编编程的旅途中一切顺利! 第一天--开始NES汇编 第二天--源代码文件结构 第三天--关于NES编程 第四天--制作并载入调色板 第五天--显示主角

NESASM教程——第一天——开始NES汇编

[关于NES汇编] 我的天,你正准备学习用汇编写NES程序?那么,如果你真想这么做,本文应该有所帮助.也许你已经读过我的正在进行中的GameBoy高级汇编系列文章.在我的GBA汇编教程中,指出你在进行汇编编程前应该先了解GBA C语言编程.我对于NES汇编也这样说,但是针对NES CPU没有好的C编译器.所以我只想说,写NES代码前要了解点GBA汇编或Intel 汇编,因为NES相比前面两者有点难. 我们将使用NESASM.exe作为我们的汇编器.可以从这里下载(http://patater.c

NESASM教程——第四天——制作、载入调色板

[啥?!] 然.今天将创建并载入调色板.为了创建调色板,我们将使用程序PAL.exe,我在第一天给你的那个zip文件中有这个.运行它,你将看到一个窗口,有32个灰色的盒子,你可以从底部彩色盒子中选取绘制颜色填充它们.当你制作调色板时一定要保证每行第一个颜色是黑色,否则你后面制作背景和主角时会看到很多意外的东西. 保存调色板为our.pal. *新的段落:什么是调色板,简单直接* *如果我本文后面说了一些和这段矛盾的东西,忽略它* 调色板基本上是一组可供选择的颜色.我们的调色板有32种颜色,占用3

NESASM教程——第五天——主角出场

[主角] 主角和背景比起来,你肯定觉得背景会更简单.错!主角才简单得要命. 制造主角只需要向SPR-RAM写入一点点内容(主角的x,y坐标,tile编号,等等). 等等,我觉得咱们得先绘制主角的图片才行,走起~:) [Tile Layer Pro] 存储主角像素块的表格称为Pattern Table,大小4KB,位于PPU $0000~$0FFF或$1000~1FFF(由PPU 控制寄存器设置,见第三天内容). 绘制像素块的工具可以用Tile Layer Pro,我们从一个空白的像素块开始. 运

NESASM教程——第十天——主角DMA

[主角DMA?] 是的,主角DMA.你还记得我们怎么利用$2003和$2004寄存器写入SPR-RAM(OAM)的吗?实际上真实系统中这种做法是不可靠的.我们应该利用内存作为OAM,然后向一个寄存器写入值,所有内容都自动拷贝到真实OAM.如果你不懂,那我们做一遍就懂了. [什么内存?] 就像我上面说的,我们需要使用"变量"内存来复制一份OAM.本教程使用$0300用于复制的OAM.注意NES上只有64个主角(占用64*4B=256B,0x100).所以基本上你自己定义的变量尽可能放在$

NESASM教程——第八天——比较

[什么意思?] 实话实说,我忘了在第6天讲比较指令,所以放在第8天了. [怎么做?] 一共有3个比较指令: CPX -- 比较X和一个值 CPY -- 比较Y和一个值 CMP -- 比较A和一个值 注意:这个"值"可以是数字,或内存变量 你注意到没,居然没有寄存器之间的比较指令,奇怪不? 使用例子: cpx #32 ; 比较X和立即数32 cpy $2002 ; 比较 Y 和 存在$2002的内容 cmp #$20 ; 比较A和0x20 beq IfEqual ; 如果比较结果为相等,

NESASM教程——第二天——源文件的结构

[发生了什么?] 嗯,你是个NES小白程序员,今天我们将学习一个NESASM代码文件的结构.不幸的是,我们的汇编器对缩进非常讲究,一行的开始位置只能放标签,放其他所有内容都必须加一个[TAB]键缩进.尽管这样听上去很糟糕,但这样确实提高了可读性,让你更容易理解代码,尤其是大程序. [关于段(Bank)] 不不不,Bank不会帮你拿着你的钱,它们帮你拿着你的程序和数据.我们将经常用三个段: 段 0 -- 放我们的代码,起始于$8000 段 1 -- 中断向量表,很重要,起始于$FFFA 段 2 -

NESASM教程——第七天——使用内存

[从哪里获得?] 我们做任何其他事情之前,最好展示怎么使用内存用于我们自己的数据.这个数据可能是任何东西,例如你需要存储的数字或主角的X/Y坐标值.我们将使用自由内存:位于CPU $0000. [怎样使用?] 代码段0用ORG伪指令定位到$0000,为一些内存贴上标签,然后ORG定位到$8000开始我们的代码. 创建一个带标签的内存(也就是创建一个变量),可使用汇编操作.db,就像这样: .bank 0 .org $0000 label1: .db 0 byte1: .db $A5 ; .db后

NESASM教程——第十一天——JSR指令

[JSR?] JSR代表Jump to SubRoutine,跳转到子程序,作用就是,嗯,跳转到子程序.JSR代表Jump to SubRoutine,跳转到子程序,作用就是,嗯,跳转到子程序. [我们怎么用它?] 我们用它时只需要给出我们想跳转到的标签即可.例如:我们用它时只需要给出我们想跳转到的标签即可.例如: jsr OurSub ; 主程序 OurSub: ; 子程序 ; 返回指令 [怎样返回?] 当然使用RTS(ReTurn from Subroutine)指令了!所以完整版代码应该为