相关影像
快速入门
作为一款使用仅仅两节5号电池供电的便携式掌机,Game Boy Advance的内部设计着实令人印象深刻。
这款掌机沿用了任天堂标志性 的GPU。 此外,它还要引入一款相对新颖的英国产CPU,该CPU将在未来几年内迅速走红。
中央处理器 (CPU)
大多数组件被组合成一个名为CPU AGB的单一封装。 该封装包含两个完全不同的CPU:
- 运行频率为8.4或4.2MHz的夏普SM83:这不就是Game Boy上发现的同一款CPU吗!它可有效运行Game Boy(DMG)和Game Boy Color(CGB) 游戏。 如果您想了解有关这些游戏机的更多信息,请参阅我以前的文章。
- 运行频率为16.78 MHz的ARM7TDMI: 这是我们要重点介绍的新处理器,它肯定能运行Game Boy Advance游戏。
不过,这两块CPU永远不会同时运行,它们也不是什么协处理器。 搭载这颗极其老旧的夏普芯片的唯一理由只是为了向后兼容。
话虽如此,在介绍ARM芯片之前,我还是想先介绍一下该品牌CPU的历史。
剑桥奇迹
有关ARM CPU的起源及其后来声名鹊起的故事引人入胜。 在这里,我们看到了公共投资、指数式增长、错误决策和远距离合作的结合。
Acorn电脑的崛起
70年代末对英国民众来说是一个动荡的年代。 曾经在战后理想下建立起来的干预主义经济已经走到了尽头,钟摆很快摆向了自由市场改革。 在这场风暴中,以剑桥为基地的企业,如Acorn Computers,与Sinclair等公司一起,向实验室和业余爱好者销售计算机套件。 与美国和日本企业类似,Acorn计算机也依赖于6502 CPU和专有的BASIC语言。
进入上世纪80年代,英国新政府的大臣们开始在学校开展计算机扫盲项目[2]。 由于Acorn即将推出“质子”(Proton)家用电脑,该公司获得了制造经济型电脑的合同,以实现政府的愿景。 结果,BBC Micro(昵称 “Beeb”)在学校、教师和学生中获得了巨大成功。 在Micro中,Acorn采用了前卫的“Tube”接口,可以通过第二个处理器扩展计算机。 这为Acorn的下一项重大投资铺平了道路。
在开发下一款以企业为重点的产品时,Acorn没有找到合适的CPU来接替6502。 面对日本和美国的竞争,Acorn面临着创新的压力,再加上计划不周,Acorn 的财务状况陷入了困境。 因此,Acorn成立了一个新的部门,负责生产引人注目的CPU。 为了绕过Acorn最近的限制,CPU团队根据一篇名为《精简指令集计算机案例》[3]的研究论文及其原型RISC CPU[4],建立了自己的架构。 最后,在1985年,Acorn将ARM1 CPU作为BBC Micro的Tube模块交付使用,但仅用于研发目的的市场推广。 直到1987年,随着第一台Acorn Archimedes计算机的推出,ARM芯片(当时为ARM2 CPU)才开始占据核心地位。
新的CPU风险投资
在Acorn Archimedes的商业化过程中,苹果公司被Acorn的高能效CPU所吸引,但这家美国公司仍然不相信Acorn最新的ARM3会适合苹果公司的新项目Newton。 不过,双方并没有放弃(毕竟Acorn是竞争对手),而是讨论了改进ARM3以满足苹果要求的可能性[5],即可变时钟频率、集成MMU和完整的32位寻址。
这种合作很快变成了一种伙伴关系,Acorn、苹果和VLSI(ARM芯片制造商)成立了一家新公司,专门致力于开发ARM CPU。 苹果公司提供投资(获得43%的股份),Acorn公司分担员工,VLSI公司负责生产。 1990 年,Advanced RISC Machines(ARM)公司成立,Robin Saxby担任执行董事长。
数年后,苹果终于推出了采用ARM610的Newton MessagePad。ARM610是新一代ARM芯片之一,集成了苹果的投入。 与此同时,Acorn也发布了使用新CPU的RiscPC。
现在,当Acorn和苹果在电脑/手持设备市场上徘徊不前时,ARM却设计出了一种激进的商业模式。 Saxby的愿景是远离制造业,以CPU设计和指令集的形式授权ARM的知识产权[6]。 这使ARM获得了计算机领域以外的客户,如德州仪器[7],后者后来将公司与新兴的移动市场(最终推出了诺基亚6110)和机顶盒联系起来。 在接下来的几年中,ARM的技术将被捆绑到数十亿台移动设备中[8]。
任天堂的合作伙伴关系
回到日本,通过对Game Boy的分析,我们了解到任天堂的便携式系统硬件战略倾向于采用片上系统(System On a Chip,SoC)模式。 这使该公司能够将负担得起的现成技术模糊化,并与内部开发相结合。 这样,新游戏机就可以独树一帜,具有竞争力。
幸运的是,ARM的许可模式正好满足了这些需求。 两家公司从1994年(Virtual Boy推出的前一年)起就开始了谈判,但直到多年后才有了结果[9]。 原因很简单:日本人认为ARM的代码密度和对32条数据线的需求不可行(Virtual Boy的CPU已经成功摆脱了这一点)。 尽管如此,ARM的新CPU设计师Dave Jaggar很快就推出了ARM7TDMI,这款新CPU的重点是在功耗和存储限制条件下最大限度地提高性能。 这对ARM来说是一个转折点,因为这款新产品不仅让任天堂感到高兴,还引起了德州仪器、诺基亚和手机领域其他竞争对手的注意。
不出所料,当任天堂开始开发Game Boy Color的后续产品时,他们选择的CPU变成了ARM7TDMI。
ARM7TDMI
现在让我们深入了解一下这款芯片的功能。
指挥 CPU
首先,ARM7TDMI实现了ARMv4指令集,即ARMv3的后续版本。 这意味着:
- 基于RISC的设计: 如前所述,ARM CPU受到了加州大学伯克利分校一篇名为《精简指令集计算机案例》[10]的论文的影响。 该论文概述了一系列可扩展处理器设计指南,并为使用存-取架构、固定指令大小和大型寄存器文件进行辩护。 在当时的CPU市场(即英特尔 8086、MOS 6502、Zilog Z80和摩托罗拉 68000)中,许多指令集都不存在,但在整个 80 年代和 90 年代,这些指令集对新CPU系列的设计产生了影响。
- 条件执行:ARM ISA的一个特殊功能。 从本质上讲,几乎每条指令都包含一个条件,说明是否应该执行。 通常,其他CPU遵循“比较和跳转”过程(也称为 “分支”)来控制CPU必须执行哪些指令。 相比之下,ARM程序员可以在指令本身插入条件。 这是因为ARM操作码的前四位保留给了条件(即
等于
、不等于
等)。 总而言之,这降低了ARM代码的复杂性,因为与分支和子程序分割不同,条件执行提供了更简洁的例程设计。 此外,这也是控制冒险的一种解决方法(稍后会有更详细的解释)。 - 32位和64位乘法指令:这是ARM v4的新增功能。 此外,64位运算将结果输出到两个寄存器中。
封装
既然我们已经知道了开发人员如何与芯片对话,那就来看看芯片内部有什么吧。
核心
就电路而言,ARM7TDMI是ARM710的缩小版,但增加了一些有趣的功能。 该核心包括[11] [12]:
- 16个通用32位寄存器: 虽然与SM83/Game Boy的7个8位寄存器相比,这是一个很大的进步,但这是对RISC准则的妥协,因为 RISC 准则要求32个32位寄存器。 这是因为ARM希望保持较小的芯片尺寸[13]。
- 32位数据总线和ALU:这意味着它可以在不消耗额外周期的情况下移动和操作32位数值。
- 干净的32位寻址: 这是苹果投入的一部分。 前三代ARM CPU使用26位内存地址来优化性能(程序计数器和状态寄存器可合并为一个32位字),以换取内存寻址能力(最多可访问64 MB内存)。 后续的ARM6系列(采用ARMv3 ISA)实现了32位寻址逻辑,但为旧代码保留了向后兼容模式。 现在,ARM7TDMI(专注于移动设备)取消了26位模式,只保留了32位寻址逻辑(减少了所需硅的面积)。
- 无内存管理单元 (MMU): 从ARM1开始,ARM就提供了MMU解决方案。 首先是作为“MEMC”协处理器,然后与ARM610集成。 现在,ARM7TDMI似乎是其系列中唯一不提供MMU的产品,这可能是由于缺乏兴趣(早期的移动设备不需要复杂的虚拟内存)。
- 无缓存: 这是该芯片降低成本的另一个原因,因为以前的ARM芯片都捆绑了一些缓存。
最后,所有这些都可以在3V电源下运行[14]。 这显然是向移动计算迈出的一步,因为早期的内核需要5V电源。
流水线
从第一次迭代开始,ARM就采用了三级流水线来运行代码。 换句话说,指令的执行分为三个步骤或阶段。 CPU能够同时对三条指令进行取指、译码与执行操作。 这样一来,CPU能够最大化地利用自身资源 (缩短闲置时间)、提升吞吐率。
与同时代的两个非常相似的处理器一样,ARM CPU也容易受到数据冒险的影响。 不过,程序员和编译器都不会注意到,因为在这种情况下,CPU会在需要时自动停止流水线。
控制冒险也同样存在,但ARM采用了一种名为条件废止(conditional annulment)的有效方法来解决它们: 每当分支指令处于第二阶段(解码)时,CPU 就会计算分支的条件[15]。 根据计算结果,如果必须执行分支指令,CPU将自动取消后续指令(将其变为填充指令)。 现在,与MIPS的方法相比(因为MIPS编译器可以插入有用的指令,而不仅仅是填充指令),这种方法可能显得效率不高。 因此,除了分支外,ARM还提供了条件执行。 后者将这种流水线设计变成了一种优势,因为ARM可以在同一流水线阶段对指令进行解码并计算其嵌入条件。 因此,在这种情况下,无需添加填充指令。 这就是为什么在为ARM CPU编程时,条件执行比分支更受欢迎的原因[16]。
挤压性能
存-取架构的缺点之一是ARM的代码非常稀疏。 x86等竞争对手可以使用更少的代码执行相同的任务,所需的存储空间也更小。 因此,当任天堂看到ARM的最新设计ARM7时,他们并不满意。 ARM指令的大小意味着,假设的由16位总线和有限内存及存储空间组成的小工具——所有这些都是为了节约成本和能源——将使CPU效率低下并陷入瓶颈。 幸运的是,Dave Jaggar刚刚完成了ARM7的设计,他还没有放弃。 在与任天堂会面后的通勤途中,他想到了一个解决方案:Thumb指令集[17]。
Thumb是ARM指令集的一个子集,其指令被编码为16位字(而不是32位)[18]。 由于是16位,Thumb指令只需要一半的总线宽度,占用一半的内存。
Thumb的主要缺点是不提供条件执行,而是依赖分支。 此外,它的数据处理操作码只使用两地址格式,而不是三地址格式,而且只能访问寄存器文件的下半部分(因此,只有8个通用寄存器可用)。 总之,由于Thumb指令只提供ARM的一个功能子集,开发人员可能需要编写更多的指令才能达到同样的效果。
实际上,Thumb使用的空间是ARM代码的70%。 对于16位宽内存,Thumb运行速度比ARM快。 如果需要,ARM和Thumb指令可以在同一程序中混合使用(称为互通),这样开发人员就可以选择何时何地使用每种模式。
扩展
ARM7TDMI本质上是一个符合ARMv3标准的附加内核。 后者在其名称(TDMI)中有所提及,意为:
- T→Thumb: 包含Thumb指令集。
- D→调试扩展(Debug Extensions): 提供 JTAG 调试。
- M→增强乘法器(Enhanced Multiplier): 以前的ARM内核需要多个周期才能计算完整的32位乘法运算,这一增强功能将其减少到几个周期。
- I→嵌入式ICE宏单元(EmbeddedICE): 启用硬件断点、观察点,并允许在调试代码时停止系统。 这有助于为该CPU开发程序。
总之,这使ARM7TDMI成为移动和嵌入式设备的一个极具吸引力的解决方案。
内存位置
Thumb的加入尤其对这款游戏机的最终设计产生了很大影响。 任天堂在不同模块之间混合使用16位和32位总线,以降低成本,同时为程序员提供优化代码所需的资源。
Game Boy Advance的可用内存分布在以下位置(从快到慢排列)[19]:
- IWRAM(内部WRAM)→32位,32 KB:用于存储ARM指令。
- VRAM(视频 RAM)→16位,96 KB:虽然该块专用于图形数据(将在本文下一节中解释),但它仍位于CPU的内存映射中,因此如果IWRAM不够用,程序员可以存储其他数据。
- EWRAM(外部WRAM)→16位,256 KB:CPU AGB旁边的独立芯片。 它是小块存储纯Thumb指令和数据的最佳选择。 另一方面,该芯片的访问速度比IWRAM慢六倍。
- Game PAK ROM→ 16 位,大小可变: 这是访问卡带ROM的地方。 虽然它可能是速度最慢的存储器之一,但它在内存映射中也有镜像,以管理不同的访问速度。 此外,任天堂还安装了一个预取缓冲器(Prefetch Buffer),与卡带接驳,以减轻过多的卡顿。 当中央处理器不访问卡带时,该组件会独立缓存连续地址,最多可容纳8个16位字。
- 但实际上,CPU很少会让预取缓冲器发挥其作用。 因为默认情况下,CPU会不断从卡带中获取指令以继续执行[20](这也是IWRAM和EWRAM如此重要的原因)。
- Game PAK RAM→8位,大小可变: 这是访问卡带RAM(SRAM或闪存)的地方
- 这是一条严格的8位总线(CPU会在未使用的位中看到“垃圾”),因此任天堂规定只能通过其库进行操作。
虽然这款游戏机被作为32位系统销售,但其大部分内存只能通过16位总线访问,这意味着游戏大多会使用Thumb指令集,以避免每次指令取用花费两个周期。 只有在非常特殊的情况下(即需要使用Thumb中没有的指令,同时将其存储在 IWRAM中),程序员才会ARM指令集中获益。
成为Game Boy Color
除了包含GBC硬件(夏普SM83、原始BIOS、音频和视频模式、兼容卡带插槽等)外,还需要两个额外功能才能实现向后兼容。
在硬件方面,游戏机依靠开关来检测插入的是Game Boy还是Game Boy Color卡带。 卡带插槽中的形状检测器可有效识别卡匣类型,并允许CPU读取其状态。 假设CPU AGB的某个组件读取了该值,并自动关闭GBC模式下不需要的硬件。
从软件方面来看,有一个名为REG_DISPCNT
的16位特殊寄存器可以改变显示屏的许多属性,但其中一位会将游戏机设置为“GBC模式”[21]。 起初,我很难理解GBA究竟何时会尝试更新这个寄存器。 幸运的是,一些开发人员帮我澄清了这个问题:
我认为在GBC启动过程中发生的事情是:检查开关(可在REG_WAITCNT 0x4000204读取),进行淡入(淡入速度非常快,很难察觉),然后最终切换到GBC模式(BIOS写入REG_DISPCNT 0x4000000),停止ARM7。
谜题中唯一缺少的部分是,如果移除GBC卡带外壳的一部分,使开关不再按下,然后通过软件模式切换到GBC模式,会发生什么情况。 多重启动模式在这方面会有所帮助。 我不确定GBC卡带总线是否需要按下开关才能正常工作,或者它只是工作而已。 我猜开关是总线工作的必要条件,但这只是猜测。
– Dan Weiss (又名 Dwedit, PocketNES与Goomba Color的维护人员)
图形
在我们开始之前,你会发现该系统是SNES和Game Boy的混合体。 事实上,图形核心仍被称为PPU。 因此,我建议大家先阅读这些文章,因为我将重温许多以前解释过的概念。
与以前的Game Boy相比,我们现在有了一个液晶屏幕,可以显示多达32768色(15位)。 它的分辨率为240x160像素,刷新率为约60 Hz。
硬件组织
图形分布在这些内存区域中:
- 96 KB 16位VRAM(视频 RAM): 其中64 KB存储背景,32 KB存储精灵。
- 1 KB 32位对象属性内存(Object Attribute Memory,OAM): 最多可存储128个精灵条目(不是图形,只是索引和属性)。 如其大宽度所示,OAM的总线专为快速访问而优化。
- 1 KB 16位调色板RAM(Palette RAM,PAL RAM): 存储两个调色板,一个用于背景,另一个用于精灵。 每个调色板包含256个条目,每个条目有15位颜色,其中颜色
0
表示透明。
构造帧
如果你读过前面的文章,你就会发现GBA并不陌生,不过它还有一些额外的功能可能会让你大吃一惊。 无论如何,新系统只需两节AA电池即可运行这一事实让本研究更加令人着迷。
我将借用世嘉的索尼克进化3(Sonic Advance 3)的画面来展示一帧画面是如何构成的。
图块
GBA 的图块是严格的8x8像素位图,可以使用16种颜色(4bpp)或256种颜色(8bpp)。 4bpp图块占用32个字节,而8bpp图块占用64个字节。
图块可以存储在VRAM的任何位置。 不过,PPU希望将它们分组为字符块:16 KB的连续区域。 每个字符块保留给特定类型的图层(背景或精灵),由程序员决定每个字符块的起始位置。 这可能会导致一些重叠,从而使两个字符块可以共享相同的图块。
由于字符块的大小,每个字符块最多可存储256个8bpp图块或512个4bpp图块。 总体而言,最多可分配6个字符块,总共需要96 KB内存: 这正是游戏机所拥有的VRAM容量。
只有四个字符块可用于背景,两个可用于精灵。
背景
该图层将在某些扫描线上水平移动,以模拟水的效果
自Game Boy Color推出以来,该系统的背景层有了很大改进。 它终于包含了超级任天堂中的一些功能(还记得仿射变换吗?)
PPU 最多可以绘制四个背景层。 每个图层的功能取决于所选的运行模式[22]:
- 模式0:提供四个静态图层。
- 模式1:只提供三个图层,但其中一个是仿射图层(可旋转和/或缩放)。
- 模式2:提供两个仿射层。
每个图层的尺寸最大为512x512像素。 如果是仿射层,则最大尺寸为1024x1024像素。
定义背景图层的数据称为图块地图。 现在,这些信息以屏幕块(screenblocks)的形式编码:一种定义背景层部分(32x32图块)的结构。 一个屏幕块仅占2 KB,但构建整个图层需要多个屏幕块。 程序员可以在VRAM的任意位置放置屏幕块,这些屏幕块可能会与背景字符块重叠。 这意味着并非所有图块条目都包含图形!
精灵
精灵的大小可以达到64x64像素。 然而,在如此小的屏幕上,精灵最终会占据屏幕的很大一部分。
如果这还不够,PPU现在还能对精灵进行仿射变换!
精灵条目有32位宽,其值可分为两组:
- 属性: 包含x/y位置、水平/垂直翻转、大小、形状(正方形或矩形)、精灵类型(仿射或常规)和第一个图块的位置。
- 仿射数据: 仅用于仿射精灵。 它们指定了缩放和旋转。
结果
一如既往,PPU会自动合并所有图层,但这还没有结束! 系统有几种效果可以应用在这些图层上:
- 马赛克:使图块看起来更加方方正正。
- Alpha混合: 结合两个重叠图层的颜色,产生透明效果。
- 窗口效果: 将屏幕分成两个不同的窗口,每个窗口都可以有自己独立的图块和特效,两个窗口的外部区域也可以用图块渲染。
另一方面,有多个选项可用于更新帧:
- 命令CPU: 处理器现在可以随时完全访问VRAM。 不过,如果它在帧中改变某些数据,可能会产生不必要的假象,因此在大多数情况下,等待垂直/水平消隐(VBlank/HBlank)(传统方法)仍然是最安全的选择。
- 使用DMA控制器:DMA传输速率快10倍,可在 垂直/水平消隐期间调度。 该游戏机提供四个DMA通道(两个预留给声音,一个用于关键操作,另一个用于通用)。 请注意,在操作过程中,控制器将使CPU停止运行(尽管CPU几乎不会注意到这一点!)。
超越图块
有时,我们可能想制作一个背景,而图块引擎无法从中绘制出所有需要的图形。 现在,现代游戏机通过帧缓冲区架构解决了这一问题,使程序员可以单独任意改变每个像素。 然而,在内存极小的情况下,这是不可能实现的…… 而GBA恰好有96 KB的 VRAM。 这足以分配一个与我们的LCD屏幕一样大小的位图。
好消息是,PPU通过三种额外模式实现了这一功能,这些模式被称为位图模式[23]:
- 模式3:分配一个全彩(16bpp,32768色)帧。
- 模式4:提供两个帧,每个帧只有一半的颜色(8bpp,256色)。
- 模式5:提供两个全彩帧,每个帧的大小减半(160x128像素)。
使用两个位图的原因是为了实现翻页功能(page-flipping): 在显示的位图上绘图可能会在过程中出现一些奇怪的假象。 如果我们改用另一个位图,用户就不会看到任何异常。 一旦第二个位图绘制完成,PPU 就可以更新以指向第二个位图,从而有效地交换显示的帧。
位图模式允许CPU为场景提供一些基本的3D图形
前景对象是精灵(独立图层)。
使用一些基元对位图进行渲染
注意屏幕上没有显示由图块引擎产生的明显图案
作为GBA视频卡带发行的剧集(当然,它受到了很大的压缩)。
总的来说,这听起来像是一项尖端功能,然而,大多数游戏都坚持使用图块引擎。 为什么呢? 因为在实践中,它耗费了大量的CPU资源。
图块引擎使CPU能够将大部分计算工作委托给图形芯片。 相比之下,PPU提供的帧缓冲区系统仅限于将该内存段显示为单个背景层,这意味着除非CPU进行计算,否则无法再进行单独的仿射变换、分层或特效。 此外,帧缓冲区占用80 KB内存,因此只有16 KB(一半)可用来存储精灵图块。
因此,这些新模式主要用于特殊情况,如播放动态视频(Game Boy Advance Video系列完全依赖于此)或显示3D几何图形(由CPU渲染)。 无论如何,其结果至少可以说是令人印象深刻的。
音频
GBA具有双声道采样播放器,可与传统的Game Boy音效系统结合使用。
功能
下面以索尼克进化2为例,对每个音频组件进行细分:
PCM
新的声音系统现在可以播放PCM采样,它提供两个称为直接声音(Direct Sound)的通道,使用FIFO队列(以16字节缓冲器的形式实现)接收采样。
采样是8位有符号的(编码值从-128到127)。 默认采样率为32 kHz,但这取决于每款游戏:因为采样率越高,文件大小越大,CPU周期越长,所以并不是每款游戏都会花费同样多的资源在音频芯片上。
DMA 可以用来节省CPU的工作开销。 定时器也可与队列保持同步。
PSG(可编程声音生成器)
虽然Game Boy子系统不会共享其CPU,但它可以访问其PSG。 出于兼容性考虑,这与原始Game Boy上的设计相同。 我以前写过一篇文章,详细介绍了每个通道的具体情况。
大多数GBA游戏都将其用于伴奏或效果。 后来的游戏会将音乐优化为PCM,而不使用PSG。
混合后
最后,所有声音都会自动混合并通过扬声器/耳机插孔输出。
尽管GBA只有两个PCM通道,但一些游戏似乎能够“同时”播放两个以上的采样。 它是如何实现的? 虽然只有两个通道在纸面上看起来有点弱,但主CPU可以使用其部分周期来提供音频排序和混音[24](这应该能让你了解 ARM7 有多强大!)。 此外,在“操作系统”部分,你会发现BIOS ROM中包含了音频编曲器!
两全其美
有些游戏进一步采用了PCM-PSG双重性,并根据具体情况“交替”使用主导芯片。
在这款游戏(地球冒险3(Mother 3))中,玩家可以进入两个不同的房间,一个是相对正常的房间,另一个是怀旧的房间。 根据角色所处房间的不同,同样的乐谱听起来会偏现代或偏8bit。
操作系统
ARM7的Reset向量表位于0x00000000
处,该地址指向一块16 KB大小的BIOS ROM。 这意味着Game Boy Advance首先从BIOS启动,BIOS会显示标志性的启动动画,然后决定是否加载游戏。
BIOS ROM 还存储了软件例程,游戏可以调用这些例程来简化某些操作并减小卡带的大小[25]。 这些例程包括:
- 算术功能:执行除法、平方根和反正切运算的例程。
- 仿射矩阵计算:在给定“缩放”值和角度的情况下,它将计算出输入PPU的仿射矩阵,以便缩放/旋转背景或精灵。
- 有两个函数,一个用于精灵,另一个用于背景。 它们的参数略有不同,但原理相同。
- 解压缩函数:执行解压缩算法,包括Run-Length、LZ77和Huffman。 它还提供位解包和顺序差。
- 内存复制:两个移动内存的函数。 第一个函数使用专门的操作码复制32字节块,这种类型的传输(
LDMIA
加载和SDMIA
存储)只需一次。 第二个函数分别使用重复的LDRH/STRH
或LDMIA/STMIA
操作码复制2字节或4字节的数据块。 因此,第二个功能更加灵活,但速度却没有那么快。 - 声音:实现完整的MIDI音序器! 它包括许多控制功能。
- 电源接口: 用于复位、清除大部分RAM、停止CPU直到某个事件发生(垂直消隐或自定义事件)或切换到“低功耗模式”的快捷方式。
- 多重启动: 将程序上传到另一个GBA并启动它。 更多详情请参见“游戏”部分。
BIOS通过32位总线连接,使用ARM和Thumb指令组合实现,但后者最为突出。
此外,请记住,所有这些都只能在ARM7上运行。 换句话说,没有任何硬件加速来加快这些操作。 因此,任天堂通过软件提供了所有这些功能。
游戏
游戏以一种新的专有卡带格式分发,它仍被称为Game Pak,但采用了更小的设计。
GBA程序大多用C语言编写,性能关键部分用汇编语言(ARM和Thumb)编写,以节省时钟周期。 任天堂提供了一个包含库和编译器的SDK。
GBA的编程与超级任天堂共享一些方法,但也继承了2000年代早期的所有先进技术: 标准化的高级语言、可靠的编译器、可调试的RISC CPU、非专有的开发工作站、相对更好的文档以及…… 互联网的接入!
访问卡带数据
虽然ARM7具有32位地址总线,但连接到卡带的地址线只有24条。
这意味着,从理论上讲,不需要映射器就可以访问卡带上最多16 MB的内容。 然而,内存映射图显示可以访问32 MB的卡带ROM。 那么,这到底是怎么回事呢? 事实上,Game Pak使用的是25 位地址(这也是32 MB为一块的原因),但其最下面的位被固定为0。 因此,剩下的24位都被设置了。 这就是Game Pak寻址的工作原理。
这是否意味着位于奇数地址(最小有效位为1
)的数据将无法访问? 不会,因为数据总线是16位的: 每次传输时,CPU/DMA都会获取所在字节和下一个字节,从而能够读取偶数和奇数地址。 正如您所看到的,这只是充分利用硬件功能同时降低成本的又一项工程。
奇怪的是,26位ARM CPU也采用了同样的技术。 这些处理器采用24位程序计数器,由于位数必须是8 的倍数(又称 字对齐),因此26位地址的最后两位总是0。 不过,由于这些CPU取32位(第一个字节加上后面三个字节),因此可以访问整个26位地址空间。
卡带RAM空间
为了保存存档,卡带可以包括[27]:
- SRAM:它们需要电池来保存内容,大小可达64 KB(尽管商业游戏不超过32 KB)。 可通过GBA的内存映射访问。
- 闪存ROM:与SRAM类似,不需要电池,容量可达128 KB。
- EEPROM:需要串行连接,理论上可存储任何内容(通常为8 KB)。
配件
包括以前的Game Boy Link插口,可提供多人游戏功能或额外内容。 但由于某种原因,该机不再配备红外传感器(可能是大容量传输太不可靠)。
此外,GBA的BIOS在内部实现了一种称为多重启动的特殊功能: 另一台游戏机(GBA或GameCube)可以向接收器的EWRAM发送一个可用的游戏,然后,后者将从那里启动(而不是从Game Pak启动)。
反盗版&自制软件
一般来说,与其他游戏机制造商在使用CD-ROM时不得不不断进行的“猫捉老鼠”游戏相比,使用专有卡带对破解者来说是一个很大的障碍。
为了打击盗版卡带(未经授权的复制品),GBA的BIOS加入了与初代Game Boy相同的启动检查功能。
烧录卡
随着固态存储变得越来越经济实惠,市场上出现了一种新型卡带。 烧录卡与普通的卡带外观相似,但增加了一个可重复写入的存储器或一个卡槽。 这样,用户就可以在游戏机内启动游戏ROM文件。 实际上,这个概念并不新鲜,开发人员在内部就使用过类似的工具,在真正的游戏机上测试他们的游戏(制造商提供了实现这一功能的硬件)。
早期的解决方案包括一个可烧录的NOR Flash闪存(最多32 MB)和一些电池后背供电的SRAM。 为了将二进制文件上传到卡带中,卡带随附了一根链接到USB的电缆,可与GBA和运行Windows XP的PC配合使用。通过使用专有的闪存软件和驱动程序,电脑将多重启动程序上传到 GBA,再由 GBA 将游戏二进制文件从电脑传输到闪存卡(插入 GBA 中)。总之,上传游戏的整个过程被认为过于缓慢。后来的闪存卡(如 “EZ-Flash”)提供了更大的存储空间,并且无需 GBA 作为中间媒介即可进行编程[29]。最后的闪存卡依赖于可移动存储器(SD、MiniSD、MicroSD 或其他)。 通过使用专有的烧录软件和驱动程序,电脑将多重启动程序上传到GBA,再由GBA将游戏二进制文件从电脑传输到烧录卡(插入GBA中)。 总之,上传游戏的整个过程被认为过于缓慢。 后来的烧录卡(如“EZ-Flash”)提供了更大的存储空间,并且无需GBA作为中间媒介即可进行编程[29]。 后一种烧录卡依赖于可移除存储器(SD、MiniSD、MicroSD或其他)。
事实证明,这些存储卡的商业应用是一个法律的灰色地带: 任天堂谴责使用这种卡会导致盗版,而一些用户则辩解说这是运行自制程序(在游戏工作室之外制作的程序,因此未经任天堂批准)的唯一方法。 支持任天堂论点的事实是,EZ-Writer等闪存盘可以帮助用户修补游戏ROM,使其可以在EZ-Flash卡中顺利运行。 在任天堂的法律尝试之后,这些卡带在一些国家(如英国)被禁止使用。 尽管如此,它们在全球范围内依然存在。
这就是全部了,伙计们。
可惜这机子没有背光!