Game boy模拟器(5):集成
集成
- GPU寄存器
- 实现:GPU 寄存器
- 零页 I/O:GPU
- 寄存器处理
- 运行中的每帧
- index.html:模拟器界面
- jsGB.js:重置和调度
- 测试
在第 4 部分中,详细探讨了 GameBoy 的图形子系统,并将仿真放在一起。没有一套GPU的寄存器映射在软件中处理,图形子系统不能被仿真器使用;一旦这些寄存器可用,仿真器基本上就可以进行基本使用了。
GPU寄存器
GameBoy 的图形单元在内存映射的 I/O 空间中有一系列映射到内存中的寄存器。为了获得具有背景图像的工作仿真,GPU 将需要以下寄存器(其他寄存器也可用于 GPU,将在本系列的后面部分进行探讨)。
基本 GPU 寄存器
地址 | 寄存器 | 状态 |
---|---|---|
0xFF40 | LCD and GPU control | 读 / 写 |
0xFF42 | Scroll-Y | 读 / 写 |
0xFF43 | Scroll-X | 读 / 写 |
0xFF44 | Current scan line | 只读 |
0xFF47 | Background palette | 只写 |
背景调色板寄存器之前已经被探索过,它由四个 2 位调色板条目组成。滚动寄存器和扫描线计数器是全字节值;这留下了 LCD 控制寄存器,它由 8 个独立的标志组成,用于控制 GPU 的各个部分。
GPU控制寄存器
位 | 功能 | 0 | 1 |
---|---|---|---|
0 | Background: on/off | Off | On |
1 | Sprites: on/off | Off | On |
2 | Sprites: size (pixels) | 8x8 | 8x16 |
3 | Background: tile map | #0 | #1 |
4 | Background: tile set | #0 | #1 |
5 | Window: on/off | Off | On |
6 | Window: tile map | #0 | #1 |
7 | Display: on/off | Off | On |
在上表中,GPU 的附加功能出现了:可以出现在背景上方的“窗口”层,以及可以在背景和窗口上移动的角色对象。这些附加功能将在需要时涵盖;同时,背景标志对于基本渲染功能最重要。特别是,在这里可以看到如何更改背景瓦片地图和瓦片集,只需翻转寄存器 0xFF40
中的位即可。
实现:GPU 寄存器
借助概念性的 GPU 寄存器布局,只需将这些地址的处理程序添加到 MMU 即可实现仿真。这可以通过将 GPU 更新硬编码到 MMU 中来完成,或者定义一系列寄存器,其中将从 MMU 调用 GPU,以便从那里完成更专业的处理。 出于模块化的考虑,这里采用了后一种方法。
零页 I/O:GPU
位于 MMU.js 中
rb: function(addr){switch(addr & 0xF000){...case 0xF000:switch(addr & 0x0F00){...// Zero-pagecase 0xF00:if(addr >= 0xFF80){return MMU._zram[addr & 0x7F];}else{// I/O control handlingswitch(addr & 0x00F0){// GPU (64 registers)case 0x40: case 0x50: case 0x60: case 0x70:return GPU.rb(addr);}return 0;}}}},wb: function(addr, val){switch(addr & 0xF000){...case 0xF000:switch(addr & 0x0F00){...// Zero-pagecase 0xF00:if(addr >= 0xFF80){MMU._zram[addr & 0x7F] = val;}else{// I/Oswitch(addr & 0x00F0){// GPUcase 0x40: case 0x50: case 0x60: case 0x70:GPU.wb(addr, val);break;}}break;}break;}}
寄存器处理
位于 GPU.js 中
rb: function(addr){switch(addr){// LCD Controlcase 0xFF40:return (GPU._switchbg ? 0x01 : 0x00) |(GPU._bgmap ? 0x08 : 0x00) |(GPU._bgtile ? 0x10 : 0x00) |(GPU._switchlcd ? 0x80 : 0x00);// Scroll Ycase 0xFF42:return GPU._scy;// Scroll Xcase 0xFF43:return GPU._scx;// Current scanlinecase 0xFF44:return GPU._line;}},wb: function(addr, val){switch(addr){// LCD Controlcase 0xFF40:GPU._switchbg = (val & 0x01) ? 1 : 0;GPU._bgmap = (val & 0x08) ? 1 : 0;GPU._bgtile = (val & 0x10) ? 1 : 0;GPU._switchlcd = (val & 0x80) ? 1 : 0;break;// Scroll Ycase 0xFF42:GPU._scy = val;break;// Scroll Xcase 0xFF43:GPU._scx = val;break;// Background palettecase 0xFF47:for(var i = 0; i < 4; i++){switch((val >> (i * 2)) & 3){case 0: GPU._pal[i] = [255,255,255,255]; break;case 1: GPU._pal[i] = [192,192,192,255]; break;case 2: GPU._pal[i] = [ 96, 96, 96,255]; break;case 3: GPU._pal[i] = [ 0, 0, 0,255]; break;}}break;}}
运行中的每帧
目前,模拟器 CPU 的调度循环永远运行,没有暂停。模拟器最基本的界面允许重置或暂停模拟;为了实现这一点,必须使用已知的时间量作为仿真器接口的基本单位。可以使用三种可能的时间单位:
- 指令:提供在每条 CPU 指令后暂停的机会。这会导致大量开销,因为 CPU 执行的每一步都必须调用调度函数;在 4.19MHz 频率下,必须采取许多步骤才能产生可观的数量。
- 行扫描:在 GPU 渲染每一行后暂停。这会产生较少的开销,但调度程序仍然必须每秒调用数千次;此外,在画布显示与当前扫描线不对应的状态下,可以暂停仿真。
- 帧:允许在整个帧被模拟、渲染并推送到画布后停止模拟。这提供了计时精度和最佳速度的最佳折衷,同时确保模拟画布与 GPU 状态一致。
由于每一帧由144条扫描线和10行垂直空白组成,每条扫描线运行需要456个时钟周期,因此一帧的长度为70224个时钟。与在仿真开始时初始化每个子系统的仿真器级重置功能结合使用,仿真器本身可以运行,并提供基本接口。
index.html:模拟器界面
<canvas id="screen" width="160" height="144"></canvas>
<a id="reset">Reset</a> | <a id="run">Run</a>
jsGB.js:重置和调度
jsGB = {reset: function(){GPU.reset();MMU.reset();Z80.reset();MMU.load('test.gb');},frame: function(){var fclk = Z80._clock.t + 70224;do{Z80._map[MMU.rb(Z80._r.pc++)]();Z80._r.pc &= 65535;Z80._clock.m += Z80._r.m;Z80._clock.t += Z80._r.t;GPU.step();} while(Z80._clock.t < fclk);},_interval: null,run: function(){if(!jsGB._interval){jsGB._interval = setTimeout(jsGB.frame, 1);document.getElementById('run').innerHTML = 'Pause';}else{clearInterval(jsGB._interval);jsGB._interval = null;document.getElementById('run').innerHTML = 'Run';}}
};window.onload = function()
{document.getElementById('reset').onclick = jsGB.reset;document.getElementById('run').onclick = jsGB.run;jsGB.reset();
};
测试
将这些代码组合在一起的结果:模拟器能够加载和运行基于图形的演示。在这种情况下,正在加载的测试 ROM 是由Doug Lanford编写的滚动测试:当按下方向键盘按钮之一时,显示的背景将滚动。在这种特殊情况下,在未模拟键盘的情况下,会显示静态背景。
在下一部分中,这块拼图将就位:一个键盘模拟,它可以为模拟程序提供适当的输入。
Game boy模拟器(5):集成相关推荐
- Android Nes模拟器,nes/fc任天堂/小霸王游戏SDK集成
Android Nes Emulator(Nes模拟器/FC任天堂/小霸王游戏)SDK集成 Android Nes模拟器SDK集成,一键引入,配置简单明了,链接如下↓↓↓ 欢迎留下star githu ...
- 适用于 Android 的 Visual Studio 模拟器
适用于 Android 的 Visual Studio 模拟器 https://visualstudio.microsoft.com/zh-hans/vs/msft-android-emulator/ ...
- android opengl版本太低,安卓模拟器opengl_安卓模拟器无法安装“系统opengl版本过低”的通用解决方法_安卓模拟器通用版_通用安卓模拟器...
安卓模拟器无法安装"系统opengl版本过低"的通用解决方法 在安装安卓模拟器时,出现"系统opengl版本过低",下图提示,说明你的显卡暂不支持模拟器: 遇到 ...
- MQSim模拟器论文阅读
来自论文:MQSim A Framework for Enabling Realistic Studies of Modern Multi-Queue SSD Devices 这是一个使现代多队列SS ...
- android opengl版本,安卓模拟器无法安装系统opengl版本过低的通用解决方法
在安装安卓模拟器时,出现"系统opengl版本过低",下图提示,说明你的显卡暂不支持模拟器: 遇到这个问题,主要是3种原因 1.你的电脑没有显卡 解决方案:这个问题若不换电脑硬件是 ...
- 云服务器安装安卓模拟器显示版本过低,安卓模拟器提示系统opengl版本过低无法安装解决办法...
上图说明你的显卡暂不支持模拟器,遇到这个问题,主要是3种原因: 1.你的电脑没有显卡 解决方案:这个问题若不换电脑硬件是暂时无解的,只能等待我们模拟器支持集成显卡了 2.你的电脑显卡确实不支持Open ...
- 【用PS3手柄在安卓设备上玩游戏系列】FC(任天堂NES/FC主机)模拟器
NESoid 是安卓系统下公认最好的FC模拟器.据我所知,现在安卓系统下面的绝大部分的FC模拟器,都是基于 NESoid 的内核来开发的. 官方网站:http://www.nesoid.com NES ...
- RNN失宠、强化学习风头正劲,ICLR 2019的八点参会总结
https://www.toutiao.com/a6690758737302389262/ 2019-05-14 14:02:43 上周,深度学习顶会 ICLR 2019 在新奥尔良落幕.毕业于斯坦福 ...
- ARM常用的调试方式与ARM培训班常见的调试方法
1. 指令集模拟器 部分集成开发环境提供了指令集模拟器,可方便用户在PC机上完成一部分简单的调试工作,但是由于指令集模拟器与真实的硬件环境相差很大, 因此即使用户使用指令集模拟器调试通过的程序也有可能 ...
- 零基础如何学习Java?你要注意的8件事
随着社会信息的发展,Java技术已经无处不在,无论是手机软件.手机Java游戏还是电脑软件等,只要你使用到电子产品就会碰到和Java有关的东西,更多的企业正采用Java语言开发网站.那零基础如何学习J ...
最新文章
- 8086之8253芯片仿真
- Visual Studio 2022 17.1 正式发布,5个新亮点!
- 小米出招黑科技,5S或成全球首款”Under glass“指纹识别手机
- transition动画与transform变换(了解
- IOS图标 HTML规范,IOS用户界面(UI)设计规范图表——APP设计师必看!
- 中国开发者数量全球第二,C 语言一跌再跌 | GitHub 年度报告发布
- 如何在虚拟机中安装wp8的sdk,无法启动模拟器问题
- linux sh脚本数组,Bash脚本编程之数组
- Mock Server基本使用方法
- 机场三字代码和四字代码的资料汇编
- 解决QML debugging is enabled.Only use this in a safe environment.警告
- 【异常】解决 Cannot find module ‘./element-ui‘ or its corresponding type declarations.
- canvas - 基础知识 - 绘制剪纸图形
- 软件测试面试题及答案 这个可以免费白嫖的题库不要错过了
- 基于三维实景建模与CIM的数字孪生城市建设
- 17正交矩阵和Gram-Schmidt正交化
- 四书《孟子》《论语》《中庸》《大学》五经《风》《雅》《颂》全文
- matplotlib | Python强大的作图工具,让你从此驾驭图表
- 【Python爬虫系列】为什么我喜欢python?来看看这些让人爱不释手的原因吧,购物网站大盘点,看过这些python做的项目,我立马入坑了…(神奇 | 爱了,爱了)
- 周亚军 红宝书 案例 3 telnet远程管理协议