NES基本原理(六)手柄

简介: 手柄

首发公众号:Rand_cs

Controller&Format

Controller

本文讲述 NES 的输入设备,最为常见的就是手柄 joypad:

一般支持两个手柄,手柄 1 和手柄 2 分别映射到 CPU 的地址空间 0x4016 和 0x4017,我们可以从这两个寄存器读出手柄按键的状态,1 代表按下,0 表示弹起状态。

手柄的内部有个移位寄存器来存放这些键的状态,每次从 0x4016 读取的数据只表示一个键的状态,需要连续读取 8 次才能读取所有键的状态,8 个键的读取顺序如下所示:

$$A \rightarrow B \rightarrow Seclect \rightarrow Start \rightarrow Up \rightarrow Down \rightarrow Left \rightarrow Right$$

读取 Right 后,如果继续读会一直返回 1。

手柄内部有个 strobe,可以通过写 0x4016 来设置这个 strobe,如果设为 1,手柄会不停的将当前键的状态装载到移位寄存器,此模式下,CPU 读取键位状态会一直获取键 A 的状态。如果 strobe 设为 0,会停止装载键的状态,这个模式下连续读取 8 次就是我们想要的 8 个键的状态。

看个代码好理解些:

  LDA #$01      ; strobe 设为1,装载键的状态 
  STA $4016
  LDA #$00      ; strobe 设为0,停止装载
  STA $4016     ; tell both the controllers to latch buttons

  LDA $4016     ; player 1 - A
  LDA $4016     ; player 1 - B
  LDA $4016     ; player 1 - Select
  LDA $4016     ; player 1 - Start
  LDA $4016     ; player 1 - Up
  LDA $4016     ; player 1 - Down
  LDA $4016     ; player 1 - Left
  LDA $4016     ; player 1 - Right

  LDA $4017     ; player 2 - A
  LDA $4017     ; player 2 - B
  LDA $4017     ; player 2 - Select
  LDA $4017     ; player 2 - Start
  LDA $4017     ; player 2 - Up
  LDA $4017     ; player 2 - Down
  LDA $4017     ; player 2 - Left
  LDA $4017     ; player 2 - Right

NES 手柄的工作原理就是这样,很简单,不够写一篇哪,下面就说说 NES 文件格式:

Format

NES 文件最初是 Marat Fayzullin 为了他的 NES 模拟器而定义的一种文件格式,之后就一直沿用,只是有了些更新,来看看 NES 文件是怎样的:

iNES header

byte0-2,魔数字符串 “NES”,很多文件格式的开头都有这么一个标识,比如说 elf 文件,这里也一样的道理。

byte3,包含了值 0x1A,也是标识魔数的一部分

byte4,16KB 的 PRG 的数量

byte5,8KB 的 CHR 的数量

byte6,Rom control byte 1:

  • bit0:0-水平镜像,1-垂直镜像
  • bit1:是否有 RAM 映射到 0x6000-0x7FFF,这部分可用作存档
  • bit2:是否存在 512 字节的 trainer,trainer 用于一些被修改过的游戏使其运行在不同的硬件上,比如说早期的一些 RAM 卡带,这里就要放置一些额外的兼容性代码,一般没有 trainer。
  • bit3:此位置 1 会覆写 bit0,表示 four-screen mirroring
  • bit4-7:mapper number byte 低 4 位,表示使用的哪种 mapper

byte7,ROM control byte 2:

  • bit0-3,保留,全 0
  • bit4-7,mapper number byte 高 4 位

byte8,8KB 的 RAM banks 的数量,主要是为了兼容前代的 ines 文件格式

byte9-15,保留,全 0

后面就是文件主题,如果有 trainer,那紧接着 header 的就是trainer,否则就是 PGR 和 CHR 紧跟其后。

NES 的文件格式就是这样,来看超级马里奥的例子,同样的直接使用 FCEUX 打开超级马里奥,截图如下所示:

然后再直接查看二进制文件:

byte0-3:0x4e, 0x45, 0x53, 0x1a 为 NES+0x1a

byte4:0x02,表示 16KB 的 PRG 有 2 个,说明 PRG 有 32KB

byte5:0x01,表示 8KB 的 CHR 有 1 个,说明 CHR 有 8KB

byte6-7:0x01,0x00,表示垂直镜像,mapper number 为 0

上述就是超级马里奥文件头的基本信息,可以与从 FCEUX 截的图做对比,发现是吻合的没问题。

好了本文就到这里,有什么问题还请批评指正。
首发公众号:Rand_cs

目录
相关文章
|
19天前
|
传感器
|
19天前
|
机器学习/深度学习 索引
|
19天前
|
存储 缓存 芯片
|
19天前
|
存储 索引
|
7月前
|
缓存
EasyX图形库note4,动画及键盘交互
EasyX图形库note4,动画及键盘交互
67 0
|
Python
Python实现超级玛丽游戏系列教程04背景滚动及摄像机(Camera)原理
Python实现超级玛丽游戏系列教程04背景滚动及摄像机(Camera)原理
84 0
|
Web App开发 前端开发 iOS开发
探秘神奇的运动路径动画 Motion Path
探秘神奇的运动路径动画 Motion Path
187 0
探秘神奇的运动路径动画 Motion Path
物体交互操作之鼠标拖动物体任意移动(Unity3D)
物体交互操作非常的多,比如说用鼠标拖动物体移动,用鼠标拖动物体旋转,用鼠标滑动让物体放大和缩小。 下面就用代码演示一下如何使用鼠标拖动物体移动。
|
编解码
unity3dUGUI之UI粒子特效自适应缩放
using UnityEngine; using System.Collections; using System.Collections.Generic; public class UIParticleScale : MonoBehaviour...
1534 0
|
vr&ar 图形学
【Unity3D 灵巧小知识点】☀️ | Unity通过 射线 获取 鼠标的世界坐标 和 鼠标点击的物体信息
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。
【Unity3D 灵巧小知识点】☀️ | Unity通过 射线 获取 鼠标的世界坐标 和 鼠标点击的物体信息