集成

  • 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 的附加功能出现了:可以出现在背景上方的“窗口”层,以及可以在背景和窗口上移动的角色对象。这些附加功能将在需要时涵盖;同时,背景标志对于基本渲染功能最重要。特别是,在这里可以看到如何更改背景瓦片地图和瓦片集,只需翻转寄存器 0x​​FF40 中的位即可。

实现: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):集成相关推荐

  1. Android Nes模拟器,nes/fc任天堂/小霸王游戏SDK集成

    Android Nes Emulator(Nes模拟器/FC任天堂/小霸王游戏)SDK集成 Android Nes模拟器SDK集成,一键引入,配置简单明了,链接如下↓↓↓ 欢迎留下star githu ...

  2. 适用于 Android 的 Visual Studio 模拟器

    适用于 Android 的 Visual Studio 模拟器 https://visualstudio.microsoft.com/zh-hans/vs/msft-android-emulator/ ...

  3. android opengl版本太低,安卓模拟器opengl_安卓模拟器无法安装“系统opengl版本过低”的通用解决方法_安卓模拟器通用版_通用安卓模拟器...

    安卓模拟器无法安装"系统opengl版本过低"的通用解决方法 在安装安卓模拟器时,出现"系统opengl版本过低",下图提示,说明你的显卡暂不支持模拟器: 遇到 ...

  4. MQSim模拟器论文阅读

    来自论文:MQSim A Framework for Enabling Realistic Studies of Modern Multi-Queue SSD Devices 这是一个使现代多队列SS ...

  5. android opengl版本,安卓模拟器无法安装系统opengl版本过低的通用解决方法

    在安装安卓模拟器时,出现"系统opengl版本过低",下图提示,说明你的显卡暂不支持模拟器: 遇到这个问题,主要是3种原因 1.你的电脑没有显卡 解决方案:这个问题若不换电脑硬件是 ...

  6. 云服务器安装安卓模拟器显示版本过低,安卓模拟器提示系统opengl版本过低无法安装解决办法...

    上图说明你的显卡暂不支持模拟器,遇到这个问题,主要是3种原因: 1.你的电脑没有显卡 解决方案:这个问题若不换电脑硬件是暂时无解的,只能等待我们模拟器支持集成显卡了 2.你的电脑显卡确实不支持Open ...

  7. 【用PS3手柄在安卓设备上玩游戏系列】FC(任天堂NES/FC主机)模拟器

    NESoid 是安卓系统下公认最好的FC模拟器.据我所知,现在安卓系统下面的绝大部分的FC模拟器,都是基于 NESoid 的内核来开发的. 官方网站:http://www.nesoid.com NES ...

  8. RNN失宠、强化学习风头正劲,ICLR 2019的八点参会总结

    https://www.toutiao.com/a6690758737302389262/ 2019-05-14 14:02:43 上周,深度学习顶会 ICLR 2019 在新奥尔良落幕.毕业于斯坦福 ...

  9. ARM常用的调试方式与ARM培训班常见的调试方法

    1. 指令集模拟器 部分集成开发环境提供了指令集模拟器,可方便用户在PC机上完成一部分简单的调试工作,但是由于指令集模拟器与真实的硬件环境相差很大, 因此即使用户使用指令集模拟器调试通过的程序也有可能 ...

  10. 零基础如何学习Java?你要注意的8件事

    随着社会信息的发展,Java技术已经无处不在,无论是手机软件.手机Java游戏还是电脑软件等,只要你使用到电子产品就会碰到和Java有关的东西,更多的企业正采用Java语言开发网站.那零基础如何学习J ...

最新文章

  1. 8086之8253芯片仿真
  2. Visual Studio 2022 17.1 正式发布,5个新亮点!
  3. 小米出招黑科技,5S或成全球首款”Under glass“指纹识别手机
  4. transition动画与transform变换(了解
  5. IOS图标 HTML规范,IOS用户界面(UI)设计规范图表——APP设计师必看!
  6. 中国开发者数量全球第二,C 语言一跌再跌 | GitHub 年度报告发布
  7. 如何在虚拟机中安装wp8的sdk,无法启动模拟器问题
  8. linux sh脚本数组,Bash脚本编程之数组
  9. Mock Server基本使用方法
  10. 机场三字代码和四字代码的资料汇编
  11. 解决QML debugging is enabled.Only use this in a safe environment.警告
  12. 【异常】解决 Cannot find module ‘./element-ui‘ or its corresponding type declarations.
  13. canvas - 基础知识 - 绘制剪纸图形
  14. 软件测试面试题及答案 这个可以免费白嫖的题库不要错过了
  15. 基于三维实景建模与CIM的数字孪生城市建设
  16. 17正交矩阵和Gram-Schmidt正交化
  17. 四书《孟子》《论语》《中庸》《大学》五经《风》《雅》《颂》全文
  18. matplotlib | Python强大的作图工具,让你从此驾驭图表
  19. 【Python爬虫系列】为什么我喜欢python?来看看这些让人爱不释手的原因吧,购物网站大盘点,看过这些python做的项目,我立马入坑了…(神奇 | 爱了,爱了)
  20. 周亚军 红宝书 案例 3 telnet远程管理协议

热门文章

  1. Linux操作备忘录
  2. 西门子博途v16系统要求_西门子博途扩展函数库LGF系列教程(1)-LGF_Frequency
  3. OpenGL的图形渲染过程
  4. java程序员22年终总结以及23年展望
  5. IPFS Java实现
  6. c语言 dict数据类型,Python开发基础之Python常用的数据类型
  7. 用 Python 抓取公号文章保存成 PDF
  8. 解决OBS无法使用窗口捕获以及显示器捕获的问题
  9. 根据每个国家的数据绘制世界地图(以全球疫情为例)
  10. Chrome的控制台(Console)的用法(超详细,还未细看)