模拟器制作流程
[ 第一步之前的那一步! ]
[ 第一步 - 收集资料 ]
1.0 你有什么?
1.1 别人有什么?
[ 第二步 - 整理所获得的资料 ]
[ 第三步 TVGAME 硬体的运作方式 ]
3.1 硬体周边分类
3.2 CPU及MEMORY MAP
3.2.0 CPU的功能与地位
3.2.1 MULTI-PROCESSOR的系统:
3.2.2 看起来不一样,实际又是大同小异的CPU
3.2.3 MEMORY MAP的功能
3.2.4 ROM IMAGE
3.2.5 CPU与其他周边沟通方式
3.2.6 DSP的功能
3.3 PPU(图形处理单元运作)方式
3.3.0 PPU(图形处理单元)的功能及地位
3.3.1 PPU的组成
3.3.2 VBLANK & HBLANK
3.4 SPU(声音处理单元)运作方式:
3.4.0 SPU(图形处理单元)的功能及地位:
3.4.1 SPU的组成:
3.4.2 与PPU的不同处:
3.4.3 声音处理器专用DSP的功能:
3.4.4 声音处理器的指令:
3.5 ROM & RAM AREA
3.5.0 SYSTEM ROM:
3.5.1 没有SYSTEM ROM的基版:
3.5.2 GAME ROM
3.5.3 以光碟做媒介的ROM -- CD ROM:
3.5.4 GAME ROM的MAPPER 问题:
3.5.5 如何开发游戏:
3.5.6 ROM中的程式如何控制硬体:
3.6 摇杆控制装置及钱币计数器等NMI的处理
3.6.0 摇杆通知CPU有按键按下的原理:
3.6.1 MEMORY MAP中分配给摇杆控制装置的方式:
3.6.2 钱币计数器,START键等NMI的处理:
3.6.3 非数位式摇杆的输入:
3.6.4 钱币计数器,START键等NMI的处理:
3.7 RESET处理
3.7.0 加入RESET的原因:
3.7.1 RESET的流程:
3.8 DIP SWITCH
3.8.0 加入DIP SWITCH的原因:
3.8.1 DIP SWITCH的作用方式:
3.9 BACKUP DEVICE
3.9.0 需要BACKUP DEVICE的原因:
3.9.1 存取BACKUP DEVICE的方式:
3.A DMA CONTROLLER
3.A.0 什么是DMA(DIRECT MEMORY ACCESS) CONTROLLER?
3.A.1 DMA的运作方式:
3.B 光碟机装置
3.B.0 使用CD-ROM DRIVER的原因:
3.B.1 CD-ROM的存取方式:
3.C 其他周边
[ 第四步 模拟器的运作方式 ]
4.0 模拟器与真实的硬体还是有差距的
4.1 CPU的处理
4.1.0 CPU CORE
4.1.1 套用现成的CPU CORE :
4.1.2 自己做一个CPU CORE:
4.1.3 MULTI-PROCCESSOR的场合:
4.1.4 CPU与其他周边沟通方式的处理
4.1.5 DSP的处理
4.2 MEMORY MAP的处理
4.3 PPU的处理
4.3.0 PPU的处理
4.3.1 实际绘图的动作:
4.3.2 SCREEN REFRESH
4.4 SPU运作方式:
4.5 摇杆控制装置及钱币计数器等NMI的处理
4.5.0 MEMORY MAP中处理摇杆控制装置的方式:
4.5.1 特殊指向装置的处理:
4.5.2 钱币计数器,START键等NMI的处理:
4.6 RESET处理
4.7 DIP SWITCH作用处理方式:
4.8 DMA CONTROLLER运作处理方式
4.9 光碟机装置存取方式:
4.A 档案处理:
4.A.0 档案载入
4.A.1 LOAD HISCORE FILE
4.C.2 LOAD/SAVE 随时记忆档
4.B 特殊功能:
4.B.0 抓图
4.A.1 抓音乐档
4.B.2 GUI
4.B.3 CHEAT CODE
4.B.4 CHEAT TOOL
4.B.5 DISASM
4.C 可携性版本,WINDOWS版本,更先进的模拟器架构
4.C.0 可携性的研究
4.C.1 WINDOWS版本
4.C.2 更先进的模拟器架构
[ 第五步 如何偷别人的程式及与别人交换意见 ]
5.0 如何偷别人的程式
5.0.0 模仿是进步最快的方式:
5.0.1 哪里找得到模拟器原始码?
5.0.2 看得懂别人的程式也不是件容易的事:
5.1 和别人交换意见:
[ 第六步 实际撰写一个模拟器 ]
[ 第七步 测试,除错及版本更新 ]
7.0 测试与除错是一条漫长的道路:
7.1 自己测试的盲点:
7.2 版本更新:
7.3 最少保留一份每一个版本的原始档及执行档:
[ 第八步 撰写说明文件 ]
[ 第九步 公开你的版本 ]
9.0 建立个人网页:
9.1 投稿至模拟器新闻性网页!
[ 后记 ]
[ 常用名词解释 ]
------------------------------------------------------------------------
[ 第一步之前的那一步! ]
为什么你想做一个模拟器?练习程式语言?还是你想玩很难玩到的游戏?还是你只
是单纯的想做一个模拟器?动机会影响你的热衷度,同时你也必须选定一个明确
的目标,模拟一个ARCADE的游戏,还是游戏主机?一旦选定了明确的目标,你一定
要下定决心,否则便没有完成这个模拟器的机会!在撰写模拟器时,你会遇到很多
困难,像找不到资料;为了除错,几天都很难睡觉!就算是写好了,放出来也还有一
堆莫名其妙的人抱怨一些有的没的!你唯一的报酬可能就只有成就感而已,或者
加上能玩到已经玩不到的游戏.如果你还愿意去写一个模拟器,我真的十分佩服
你!
------------------------------------------------------------------------
[ 第一步 - 收集资料 ]
1.0 你有什么?
在你想写模拟器之前,你必须要真实的检视你自己的资源,你会什么程式语言?
你对所模拟的硬体认识多少?你了解计算机内部运作的方式吗?你看不看得懂硬
体线路图?这些会影响你写不写得出一个完整的模拟器!其实程式语言的影响
也不是那么严重,还是有人可以用QUICK BASIC写出模拟器,只是效率实在不好
而已,但是其他的因素却是影响这个模拟器写不写的出来!
1.1 别人有什么?
你需要去找你想要模拟的硬体的资料,你有哪些要找的呢?
A.使用何种CPU?基版上面有多少特殊的晶片?时序速度多少?有多少相关资料?
B.有没有硬体概图(Schematics)?有没有DIP SWITCH的资料?
C.有没有MEMORY MAP?有没有软体的其他相关资料?
D.有没有别人已经写好的模拟器原始档?
你可到哪里找?
A.新闻讨论区!
B.模拟器网页的留言版!
C.模拟器新闻网页-可以知道是否有模拟器提供其原始档!
D.模拟器程式发展资源网页-可以收集到许多前人写好的文件!
E.别人的模拟器网页-也许有额外的连结可以让你找到多一点资讯!
F.如果是游戏主机,到官方网页也许有意想不到的资料!
还缺了什么?
A.CPU 手册,反组译工具!
B.也许你会需要电子元件手册,供你分别或查询元件的用途及接脚定义等!
C.适当的程式语言,适当的函式库(节省开发时间)!
------------------------------------------------------------------------
[ 第二步 - 整理所获得的资料 ]
在搜集到所有能收集的资料之后,依照我们要的部份加以分类:
硬体:
A.CPU种类&速度!次系统处理器种类&速度!
B.Schematics,DIP SWITCH,硬体线路,电路图等!
C.MEMORY MAP,摇杆接脚定义!
D.基版上的SYSTEM ROM!
E.特殊晶片的设计资料!例如图形处理晶片,声音处理晶片等!
F.画面处理的方式,图形及声音编码方式等!
软体:
A.CPU手册,反组译工具,CPU模拟程式等!
B.游戏ROM!SYSTEM ROM!
C.特殊晶片的模拟程式!
D.别人的模拟器程式,可以"偷"或是看看别人的写法!
E.函式库手册等!
------------------------------------------------------------------------
[ 第三步 TVGAME 硬体的运作方式 ]
3.1 硬体周边分类
一般说来,你可以把整个TVGAME硬体分为:
A.CPU:
一般是廉价的泛用处理器,例如68000,6502,Z80等!用来指挥整个硬体的
运作!复杂的系统甚至以多处理机协同处理!例如TAITO的双68000系统,SS
的双SH-2系统!
B.PPU(图形处理单元,VDP,GPU):
专职于图形的处理!包含PICTURE PROCCESSOR,专用RAM,专用ROM,数位类
比转换器等!常见名称的有PPU(PICTURE PROCCESS UNIT),GPU(GRAGHIX
PROCESS UNIT),VDP(VIDEO DATA PROCCESSOR),以下都使用PPU代替!
C.特殊DSP晶片
一种能快速计算数值的晶片,用来协助处理资料!
D.SPU(声音处理单元,APU):
专职于声音的处理!包含SOUND PROCCESSOR,专用RAM,专用ROM,专用DSP,
声音晶片,数位类比转换器等!名称也很多,SPU(SOUND PROCCESS UNIT),
APU(AUDIO PROCEESS UNIT ),以下用SPU代替!
E.ROM AREA:储放ROM的区域!
1.SYSTEM ROM:
类似于PC 中BIOS+OS的地位,提供开机检查,常用函式等!
2.GAME ROM:
真正游戏的程式区域!家用主机把图形,声音,及其他资料储放在一起!
但是ARCADE游戏通常会分开储放!如果细分的话,可以分为:
a.GRAPHIC ROM:储放游戏图形资料!
b.SOUND ROM:储放声音资料!
3.储放其他资料的ROM!
F.MAIN MEMORY,WORK RAM
就是主记忆体!
G.光碟机及控制周边!
只有以光碟作为储存媒介的主机才有!
H.摇杆等控制装置:
摇杆输入,RESET,钱币计数器等!
I.BACKUP DEVICE:
电池记忆,记忆卡之类的装置!
J.基版控制周边,DMA装置,外部扩充界面及装置等!
K.硬体其他周边,萤幕,电源供应器等!
当然也不是每一个TVGAME系统都这么完整,越早期的家用主机或ARCADE基版就
简单一点!现在的家用主机或是ARCADE 系统基版就十分复杂,这都是你在搜集
资料时一定要找到的,有些是模拟器一定会用到的,甚至影响模拟器的完成度,
有些则是模拟器可省略的,例如萤幕,电源供应器等!以下对于会使用在模拟器
上的装置作一下说明!
------------------------------------------------------------------------
3.2 CPU及MEMORY MAP:
3.2.0 CPU的功能与地位:
对整个TVGAME或是ARCADE来说,CPU应该算是"导演"的工作,而ROM IMAGE则是
导演手上的剧本,用来指挥周边的动作.指挥别人,当然可以不用太高级,只要
足够就行了!画面表现的好坏,声音处理的好不好,与CPU的关系较少!但是如果
周边的处理比CPU快太多,让周边老是等待也不好,同时,有一部份工作也必须
由CPU处理,所以CPU也不可能太慢!把价格与运算能力做考量依据,才选出适用
的CPU!常见的有68000,6502,Z80等!
3.2.1 MULTI-PROCESSOR的系统:
MULTI-PROCESSOR的系统就是指这个系统中含有两个以上的CPU,例如SS就是由
两个SH-2所组成的,依照CPU分工的不同,可以分为:
A.MASTER/SLAVE(非对称结构):
只有一个CPU(MASTER)负责IO的工作,计算的工作则每个CPU都能执行!同
时只有MASTER CPU能执型O.S.,而SLAVE CPU则是以中断要求MASTER的服
务!
B.SEPERATE EXECUTIVES:
每个CPU有自己的OS,INTERRUPTS,CPU种类及OS种类均允许不同,不能共同
处理同一工作!
C.SYMMETRIC ORGANIZATION:
由一个OS整合管理所有的处理机,称为PROCESSOR POOL,每个CPU皆能存取
任一I/O DEVICE及储存单元!
如果你想做的是MULTI-PROCESSOR的系统,必须要先搜集CPU间的关系,沟通方
式,例如SS就是一个MASTER/SLAVE的系统!
3.2.2 MEMORY MAP的功能:
正如家家都必须要有不同的地址,才能把邮件送到正确的地方,CPU也需要相同
的机制,用来存取到正确的资料,处理机所使用的方式是加上位址线,连接至位
址汇流排,再连接至RAM,ROM,其他装置等!位址汇流排宽度决定了CPU所能定址
的最大空间,这空间,你可称为"定址空间"!实际上不同的定址模式会影响定址
空间,不过这里我们就假装不知道吧!
为了存取方便,需要将定址空间做一番规划,规划之后的定址空间,称之为MEMORY
MAP!把定址空间分成一段一段的,把每一段都赋予不同的用途!例如下面是SFC的
MEMORY MAP!
SNES Documentation v2.30: Written by Yoshi
----------------------------------------------------------------------------
|Here's a really basic memory map of the SNES's memory. Thanks to Geggin of |
|Censor for supplying this. Reminder: this is a memory map in MODE 20. |
|----------------------------------------------------------------------------|
|Bank |Address |Description |
|-------|--------------|-----------------------------------------------------|
|$00-$3F|$0000-$1FFF |Scratchpad RAM. Set D-reg here if you'd like (I do) |
| |$2000-$5FFF |Reserved (PPU, DMA) |
| |$6000-$7FFF |Expand (???) |
| |$8000-$FFFF |ROM (for code, graphics, etc.) |
|$70 |$0000-$7FFF |SRAM (BRAM) - Battery RAM |
|$7E |$0000-$1FFF |Scratchpad RAM (same as bank $00 to $3F) |
| |$2000-$FFFF |RAM (for music, or whatever) |
|$7F |$0000-$FFFF |RAM (for whatever) |
----------------------------------------------------------------------------
不只是TVGAME及ARCADE,IBM PC也有同样的机制,例如DOS的0KB-640KB-1024KB
规划!
3.2.3 看起来不一样,实际又是大同小异的CPU:
这里先暂且搁下MEMORY MAP不谈!回到CPU,如果你有机会看到SNK NEOGEO/MVS
系统的基版的话,从文件上知道,它应该是MOTOROLA 68000的CPU,不过你就是找
不到长方形的MOTOROLA 68000 CPU,因为SNK特别订制这颗CPU,把68000及两个
PPU作在一起,成为一颗VLSI!实际上,有很多机器都是以这样的方式制作,订制
成VLSI!在写模拟器时,只需要知道它的解码方式等同于MOTOROLA 68000 CPU
就可以了!
还有一种形式是DECODE及执行结果等同于其他CPU,最明显的例子就是FC用的"
65C02",事实上它与真正的6502不太一样,只是编码及执行结果等同于6502!在
写模拟器时,仍然需要知道它的解码方式等同于6502就行了!
3.2.4 ROM IMAGE:
一般TVGAME及ARCADE游戏,都是把程式或资料烧录在ROM中-不论是ROM IC颗粒
,还是CD-ROM!很明显的,除了CD-ROM之外,没有办法直接读取其中的指令或资
料(即便是CD-ROM也可能自己搞奇怪格式,所以也可能无法读取),所以需要使
用ROM DUMPER,把ROM中的指令或资料DUMP成二进位制档案,称为"ROM IMAGE"!
因为所使用的机器语言不同(或者粗略的称为CPU不同),ROM IMAGE的内容目前
对PC并不具任何意义,所能做的也只局限在COPY,MOVE,EDIT HEX,或是ZIP起来
,类似于图形档的处理,即便它是一个受欢迎的游戏!直到有适用的模拟器出现
,ROM IMAGE才有价值--拿来玩游戏!把ROM做成ROM IMAGE,在大部分情况下都
算是比较简单,所以ROM IMAGE多,而对应的模拟器少,作ROM IMAGE只要有机器
就行,但是没人写模拟器就是白搭!
回到ROM IC上,ROM上烧录的当然是程式或资料,问题是给谁的资料!如果不考
虑有些基版有SYSTEM ROM的情况(留待SYSTEM ROM区再讨论)!ROM一般都是给
CPU的资料,所以指令都是CPU的机器语言,存取到资料区时,即便可能是给另外
PPU或SPU所使用的指令,对于CPU而言,这些仍然视作"资料"而不是"指令"!等
到这些"资料"传递给对应PPU或SPU时,才会变成"指令"!
3.2.5 CPU与其他周边沟通方式:
这里必须要先解释"MEMORY MAPPED I/O"!所谓MEMORY MAPPED I/O"是指I/O界
面位址和记忆体位址使用相同的位址空间,此时界面暂存器是记忆体系统的一
部份!界面单元和记忆体使用相同指令存取,资料位址指到记忆体,即是和记忆
体沟通;如果指到界面暂存器位址范围即是要进行I/O动作!
大部份的TVGAME及ARCADE都是设计成MEMORY MAPPED I/O,以这种方式对其周
边作存取动作,所以知道你所要模拟的系统的MEMORY MAP是很重要的事!尤其
是对PPU,SPU的存取(设定执行某一特定功能,或传递图形或声音资料),知道
细部的MEMORY MAP结构,及每个BIT的用途,才能正确的模拟出PPU,SPU的功能!
在MEMORY MAP中,属于PPU,SPU功能的段落的位址上的字组中,每一个BYTE上的
每一个BIT都有特定的用途,这些就是CPU与周边沟通的窗口!CPU把设定好的资
料,写入到正确的位址,就等于是叫PPU,SPU执行某一个特定的功能!详细的执
行这些功能的时机,我没有找到资料!比较可能执行时机可能为两种,一是CPU
直接中断PPU,SPU,然后PPU,SPU检查这些窗口,执行对应的功能!一是PPU,SPU
在定期中断CPU时,同时检查这些窗口,再执行对应的功能!不过写成模拟器时,
都是在CPU暂停的期间,PPU,SPU再去检查这些窗口,执行对应的功能!
3.2.6 DSP的功能
在大部分的情况下,CPU不需要处理大量的数字资料,所以在选择CPU时,一般并
不刻意挑选数值处理速度极快而高价的CPU,而是在CPU之外,另外搭配高速的
DSP,协助CPU处理数值资料,类似于PC上的FPU,当然PC现在都是内建的,在386
及486SX的时代,FPU是选购项目!在特殊的情况下,DSP是属于可加入式的,例如
SFC便是可在卡匣上加装DSP协助CPU处理大量多边型的运算,而不是固定在基
版上,因为它并不是必要的!不过因为需要处理的资料越来越多,新一代的TV
GAME及ARCADE系统都内建了DSP,以免数值资料处理过慢,拖累整个执行速度!
在你找资料时,也必须找到CPU与DSP沟通的方式,DSP如何处理资料,以模拟出
DSP的功能!
------------------------------------------------------------------------
3.3 PPU(图形处理单元运作)方式:
3.3.0 PPU(图形处理单元)的功能及地位:
PPU是整个TV GAME/ARCADE系统的重心,游戏画面能做到多炫,特效多少,完全
都是由PPU去表现!而CPU只是负责指挥的工作,所以使用同一个CPU的系统,如
果所使用的PPU能力不同的话,所呈现的效果也将有很大的不同!这是模拟器所
要模拟的重心,整个模拟器完成度几乎全取决于PPU及SPU是否能模拟的完美!
3.3.1 PPU的组成:
包含PICTURE PROCCESSOR,专用RAM,专用ROM,数位类比转换器等!简图如下:
PPU
┌───┐ +---------------------------+
├───┤ | ┌───┐ |
│DATA ├─┬──────┬─┬┤RAM │ |
├───┤┌┴─┐| ┌─┴┐││(VRAM)│ |
│ ││CPU ├──┤PP ││├───┤ |
│ ││ │| │ │├┤ROM │ |
│ │└──┘| └──┘││ │ |
│ │ | │├───┤ |
└───┘ | ││DAC │ |
ROM&RAM | └┤ ├──── VIDEO OUT
| └───┘ |
+---------------------------+
CPU透过MEMORY MAP中的各个窗口,与PP(图形处理器,PICTURE PROCCESSOR)沟
通并设定欲执行的功能!PP便到从ROM&RAM中搬移所要处理的资料到自己的RAM
中!接下来是功能解码,再从ROM中找出应该执行的指令,依序执行之后,写回RAM
,待萤幕更新周期时,由DAC(数位-类比转换器)转换成MONITOR能接受的讯号,
显示到萤幕!
3.3.2 VBLANK & HBLANK:
由于萤幕(MONITOR)的更新是由电子束打在对应的点,让点上的萤光质发光,藉
以显示出要显示的图形!电子束打的方式是一个接着一个,由左至右,由上至下
,因为视觉暂留的现象,人眼看到的就是整个萤幕的图形!电子束从每一行的最
右边回到下一行的最左边,这一段时间称为H-BLANK,水平空白期!同样的,电子
束会从右下角再回到左上角,准备做下一次整个萤幕的更新,这一段时间称为
V-BLANK,垂直空白期!HBLANK与VBLANK的时间长短与移动的距离有关,行移动
的HBLANK时间较短,而VBLANK的时间较长,所以PPU使用VBALNK时间做一些工作
是很重要的事!这也是写模拟器及搜集资料时非常重要的一部份!
------------------------------------------------------------------------
3.4 SPU(声音处理单元)运作方式:
3.4.0 SPU(图形处理单元)的功能及地位:
与PPU一样,SPU用来专职处理声音.在比较古早的系统中,一般并不另外搭配专
用的处理器,而是由CPU直接控制.不过因为声音资料日益增多,于是另外搭配
专用的处理器,以减轻CPU的负担!随着CPU速度的加快,所搭配的SOUND CPU也
日益高级,从Z80,变成MOTOROLA 68000,逐渐变快!
3.4.1 SPU的组成:
包含SUUND PROCCESSOR,专用RAM,专用ROM,专用DSP,数位类比转换器等!简图
如下:
SPU
┌───┐ +---------------------------+
├───┤ | ┌───┐ |
│DATA ├─┬──────┬─┬┤RAM & │ |
├───┤┌┴─┐| ┌─┴┐││ROM │ |
│ ││CPU ├──┤SP ││├───┤ |
│ ││ │| │ ├┴┤SOUND │ |
│ │└──┘| └──┘┌┤CHIP │ |
│ │ | │├───┤ |
└───┘ | ││DAC │ |
ROM&RAM | └┤ ├──── SOUND OUT
| └───┘ |
+---------------------------+
大致上与PPU的组成是一样的!
CPU透过MEMORY MAP中的各个窗口,与SP(声音处理器,SOUND PROCCESSOR)沟通
并设定欲执行的功能!SP便到从ROM&RAM中搬移所要处理的资料到自己的RAM中
!接下来是功能解码,再从ROM中找出应该执行的指令,依序执行并指挥声音晶
片(SOUND CHIP)产生实际的声音资料,传递给DAC转换成声音讯号!
3.4.2 与PPU的不同处:
最大的不同处在于MONITOR还有VBLANK&HBLANK可以做很多事!SPU则必须不间
断的产生声音输出,同时声音晶片的模拟也是一大问题,这是模拟器的一大障
碍,所以模拟器一般都是发展到一定阶段了,机器的等级也到一定速度了,才逐
渐加入声音的支援!
3.4.3 声音处理器专用DSP的功能:
因为所选用的声音处理器不一定适于处理声音资料,尤其是FM与PCM有极大的
不同,PCM需要更强大的数值运算能力,因此有些系统会加入声音处理器专用
DSP,协助声音处理器处理PCM的运算!这也是搜集资料时的重要部份!
3.4.4 声音处理器的指令:
一般来说,CPU传给声音处理器的资料,将会是这个声音处理器的指令.所以必
须加入CPU CORE处理指令解码,例如是Z80的,就必须加入一个Z80的CPU CORE,
用来处理声音资料,同样有频率及定址空间的设计,整个SPU基本上就是一个隐
含的完整电脑系统!
------------------------------------------------------------------------
3.5 ROM & RAM AREA
3.5.0 SYSTEM ROM:
在某些TVGAME或ARCADE基版上会加入所谓SYSTEM ROM,这个SYSTEM ROM有几种
功能:
A.执行开机检查程式及O.S.!
B.储放重要或常用函式!
C.储放PPU,SPU常用函式!
D.储放中断向量及中断处理常式
这样的作法,明显的可以减轻GAME ROM的成本,不用每一个GAME ROM都需要挪
出空间放置这些程式,而使得成本降低!简单的说,SYSTEM ROM就等于是PC上的
作业系统!通常设置的目的是方便游戏开发人员能方便的使用一些特殊或常用
函式,基版设计厂商则必须尽量加入需要的功能函式!所以,如果你想写的主机
上有SYSTEM ROM的话,你必须想办法DUMP下来,因为不管是CPU,或者可能有PPU
,SPU都会存取到这里,执行这里的程式!
3.5.1 没有SYSTEM ROM的基版:
大部分为单一游戏或非系统基版的情况!必须在GAME ROM中拨出空间放置等同
于SYSTEM ROM功能的程式,因为是单一游戏,可以依个别情况撰写,空间的损失
并不大!通常会在基版开机时,就会从ROM中载入并执行开机检查程式!
3.5.2 GAME ROM
除去了SYSTEM ROM的部份,剩下来的就是GAME ROM的部份,按照功能可以分成:
A.PROGRAM AREA 程式区:
提供CPU指令的区域!
B.GRAGHIX DATA AREA 图形资料区 :
提供PPU图形资料的部份!
C.SOUND DATA AREA 声音资料区:
提供SPU声音资料的部份!
D.其他资料区
不同的基版设计,处理这些ROM的方式也不同!以家用主机大部分的设计来说,
所有的ROM DATA是按照其位址分开的,从外观上不易看出,DUMP时也都是直接
DUMP成一整个ROM IMAGE FILE(目前只有FC有分开DUMP的ROM IMAGE FILE出现
)!其原因应该是卡匣的体积,面积有限,不适于分开放置!
ps: 这也可能是DUMP工具的问题,家用主机的ROM DUMPER(或称为ROM COPIER)比
较常见的都并不是一个ROM IC一个ROM IC的DUMP!
相对于家用主机的情形,ARCADE则是能够从ROM IC放置的区域分别出这颗ROM
IC的内容及用途!一般来说,在DUMP这些基版的ROM IC时,都会按照其用途或
SCHEMATICS 上的编号命名,方便识别及载入至正确位址!
3.5.3 以光碟做媒介的ROM -- CD ROM:
CD ROM的处理方式与一般的卡匣或是基版上的ROM IC载入的方式并不相同!因
为必须从CD ROM中分段载入所需要的程式段,图形资料段,声音段!所以分区的
情况不明显,而是以当时游戏进行的状况处理!
3.5.4 GAME ROM的MAPPER 问题:
如果你是准备写家用主机的模拟器的话,所要面临的便是可能出现一个ROM
MAPPER 问题,ROM MAPPER问题是指MEMORY MAP中提供给ROM的区域比实际ROM
的容量还小,于是必需存在一个切换ROM BANK的暂存器(以MEMORY MAPPING I/O
方式读写)或是其他的机制,利用这些机制与MEMORY MAP中的ROM 区域而使得
能读取到更大的GAME ROM!这些机制就被称为MAPPER,模拟出MAPPER的机制就
是MAPPER问题!目前这个问题仍然困扰着FC模拟器的作者们,因为已知的MAPPER
格式就超过40种,不管是不支援某一种MAPPER或是MAPPER程式写的不好,这都
不能使你的模拟器完美!是你在搜集资料时必须注意到的!
3.5.5 如何开发游戏:
一般来说,主机公司会提供开发工具,提供游戏厂商开发游戏!游戏厂商利用开
发工具,撰写高阶的原始程式,绘制图形,编写乐谱及音效等,经过DEBUG后,把
全部的档案经过排列之后做成转烧成ROM IC,或是直接压制成CD!
3.5.6 ROM中的程式如何控制硬体:
应该有三种方式:
A.直接控制:
在开发时撰写低阶的硬体直接控制程式,理论上效能较快且可能创造出不
同的效果!游戏厂商需对硬体有相当认识,同时开发较不易!
B.呼叫SYSTEM ROM中的函式:
算是一种间接控制的方式.写高阶程式但是以呼叫SYSTEM ROM中的函式来
控制硬体!SYSTEM ROM中的函式因为容量因素,肯定不会大到哪去也不会
太多,游戏厂商还是大部分需要自己写!效能亦相当不错!
C.利用开发工具中内附的函式:
利用开发工具是最方便的方式,开发工具内附的函式到最后仍然会展成前
面两种方式控制硬体!不过开发工具的良窳会影响到游戏的开发,这点也
是很重要!
实际上通常都是这三种方式交叉使用,端看游戏厂商的能力!
------------------------------------------------------------------------
3.6 摇杆控制装置及钱币计数器等NMI的处理
3.6.0 摇杆通知CPU有按键按下的原理:
当有按键按下时,连接在基版的控制晶片会发出对CPU发出一个中断讯号,并且
把按键资讯写入到分配在MEMORY MAP中的位址!CPU接收到这个中断讯号之后,
中断现在的工作,先处理按键输入!处理完之后,在回到中断前的程式,并根据
接收到的按键讯息做反应!看起来会像这样:
┌───┐
│ │
┌──┐ ┌────┐ ├───┤
│摇杆├─┤控制晶片├─┤ ├┐
└──┘ └────┘ ├───┤│┌──┐
│ │└┤CPU ├─ 执行
│ │ └──┘
└───┘
记忆体中存放按键资讯的位址(MEMORY MAPPED IO)
3.6.1 MEMORY MAP中分配给摇杆控制装置的方式:
因为TVGAME,ARCADE一般都是使用数位式的摇杆,也就是只有[按下]及[没按下]
两种反应,分别以1BIT代替一个按键,看起来会像这样:
上 下 左 右 B1 B2 B3 B4
┌─┬─┬─┬─┬─┬─┬─┬─┐
│7 │6 │5 │4 │3 │2 │1 │0 │
└─┴─┴─┴─┴─┴─┴─┴─┘
按键多一点的用2 byte:
上 下 左 右 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│7 │6 │5 │4 │3 │2 │1 │0 │7 │6 │5 │4 │3 │2 │1 │0 │
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
更多的按键的,像麻将,当然就继续加下去!几P就加几组了!
3.6.3 非数位式摇杆的输入:
就流程上基本上是与数位式摇杆相同!问题在于如何输入资料于给定的位址中
,随着不同的摇杆会有不同的设计,这是搜集资料时一定找到的!但是找到之后
,更严重的问题是如何对应到PC的指向装置!要是不幸找不到对应的装置,你基
本上就直接放弃好了!
3.6.4 钱币计数器,START键等NMI的处理:
NMI是指"NON-MASKABLE INTERRUPT(NON-MASKED INTERRUPT)",也就是不可遮
罩的中断!这与一般中断有何不同呢?相对于NMI,其他的中断是属于可以被暂
时忽略(称为MASK掉),CPU可稍后再处理!而NMI是CPU无论如何都必须放下手边
的工作,必须优先处理这个中断!在TVGAME系统中,PPU的VBLANK就是属于一个
NMI,因为它必须萤幕更新等动作,此时PPU必须抢到周边的使用权,它会强迫
CPU暂停手边的工作!同样的,在ARCADE系统中,像投钱,1P select,1P start,
2P select,2P start,这种动作当然是一定要优先处理!不过.有些产生NMI的
装置,如PPU,还是可以利用一些暂存器的设定,使它暂时不要产生NMI,这些暂
存器的位址,设定的方式,也是在搜集资料时要找到的!
------------------------------------------------------------------------
3.7 RESET处理:
3.7.0 加入RESET的原因:
不管是TVGAME还是ARCADE,游戏通常都是不会停止的!问题是,还是有某些情况
必须要重新开机一次,例如:进到硬体测试画面,设定DIP SWITCH,使用某些密
技,打不赢人家耍贱,就是想重新开机等等!更重要的是,不断开关电源会可能
导致硬体损坏!所以必须要有一种机制可以暂时切断电源,使系统重新开机,这
种机制便是RESET!
3.7.1 RESET的流程:
RESET的第一步当然是暂时切断电源!重新初始化CPU,周边等!载入SYSTEM ROM
进行开机测试,检查是否有需要处理特殊程序,如:进到硬体测试画面,设定DIP
SWITCH!如果没有,再载入GAME ROM,开始游戏!
------------------------------------------------------------------------
3.8 DIP SWITCH:
3.8.0 加入DIP SWITCH的原因:
因为ARCADE系统是一个赚钱的工具,一成不变的游戏在被人摸熟时,就没有人
玩了,同时还有不少游戏的参数要设定,所以需要一种方便的储存游戏参数的
工具,于是在基版上加上DIP SWITCH,只要开关拨一拨,就能设定参数!不需要
外加电源!但是新一代的基版有些就不是使用DIP SWICH,而是利用EEPROM储存
,这样就不须要用手拨DIP SWITCH了!
3.8.1 DIP SWITCH的作用方式:
说穿了,也只不过是一些逻辑电路!但是利用程式检查电路短路与否,赋予实际
的意义,例如:投多少COIN才算一次CREDIT;设定出红血看起来暴力一点;或是
无敌之类的!不过少了设定DIP SWITCH的功能,并不会有什么问题,只是没那么
完美罢了!但是DIP SWITCH是用"手"设定的,所以如果要做DIP SWITCH就要做
设定函式代替用手拨开关!当然你还是需要找到该游戏DIP SWITCH图,才能知
道各开关的定义!
------------------------------------------------------------------------
3.9 BACKUP DEVICE
3.9.0 需要BACKUP DEVICE的原因:
不是每一种游戏都能一次玩完的,例如RPG,SLG等,于是需要一种能保存资料的
装置!古早之前,是利用特殊编码的CODE来保存资料!不过这不是办法,越复杂
的游戏或是需要保存的资料越多,CODE会变得越来越长!于是出现划时代的装
置---利用电池提供SRAM的电源,把资料储存在SRAM中!一般称为"电池记忆",
但是用电池还是有问题--电池是有寿命的!新一代的便是使用FLASH ROM,不须
外加电源,可重复写入!
3.9.1 存取BACKUP DEVICE的方式:
和其他装置一样,在MEMORY MAP有保留给BACKUP DEVICE的空间,只要把资料搬
过去就行了!在此之前,当然是需要先知道MEMORY MAP的空间在哪里!
------------------------------------------------------------------------
3.A DMA CONTROLLER
3.A.0 什么是DMA(DIRECT MEMORY ACCESS) CONTROLLER?
详细的原理及机制请找计算机组织之类的书!总之就是不想让资料传输通道闲
着及减轻CPU的负担,使CPU不需要自己处理资料的搬移!于是设计了一个专门
处理资料搬移的处理器,便称为DMA CONTROLLER,处理的范围是RAM与周边I/O!
因为它也是一个处理器,所以CPU与DMA CONTROLLER的沟通是有一定程序的!如
果想写的系统也具有DMA控制器的话,就必须搜集有关DMA控制器的资料!
3.A.1 DMA的运作方式(从书上抄来的):
COMPUTER ORGANIZATION & DESIGN --- DAVID A. PETERSON/JOHN L. HENNESSY
DMA传送中有三步骤:
A.由装置本身提供DMA,而操作命令是根据记忆体位址,位元数目并在装置上
执行资料的传送.
B.DMA在装置上开始操作命令并重才汇流排.当资料可用时(从装置或记忆体
),它传送此资料.而DMA装置对读取或写入提供记忆体位址.若在汇流排上
需求资料超过一次以上,DMA 单元将产生下一个记忆体位址并启动下一次
传送.DMA使用这种机制,在不用干扰处理机情况下,它能传送数千位元组
资料.在很多DMA控制器包含一些缓冲区允许它们在传送资料或等待成为
汇流排主控器时来处理延滞时间的可塑性.
C.一旦DMA传送完成时,控制器将中断处理器,然后处理器查询DMA装置或记
忆体,是否整个操作命令成功地完成.
------------------------------------------------------------------------
3.B 光碟机装置
3.B.0 使用CD-ROM DRIVER的原因:
随着游戏的声光效果越来越好,GAME ROM的容量也随之不断上升!原来所使用
的ROM IC在应用上已经有所困难!这个困难包括两方面,卡匣的尺寸会随着ROM
IC的增加而变大,另一方面,容量越大的游戏,不是ROM IC用的更多,就是必须
改用大容量的ROM IC.而不管哪一种,显而易见地都会带来成本上升的影响,造
成卡匣价钱上升!就目前而言,解决的方式有两种:一是对资料进行压缩,仍然
使用ROM IC制成卡匣的型式,优点是保有卡匣不须等待,速度较快的优势,缺点
是就算是压缩过后,还是不一定能解决容量的问题,语音及动画都是属于不易
再压缩的资料,只好忍痛删除,例如N64!另一种解决的方式是改用CD-ROM作储
存媒体,优点是再没有容量上的限制,只要增加CD-ROM片数即可,同时成本低廉
,价钱便宜!缺点是CD-ROM的存取时间远大于卡匣!例如:一堆次世代机!
3.B.1 CD-ROM的存取方式:
CD-ROM的容量有650Mbyte,大部份使用CD-ROM DRIVER的系统,其主记忆体通常
并不足以容?#123;所有资料存放于主记忆体中,于是必须以分段读取的方式存取!
┌─────────┐
│CPU 读取某一段资料│
└────┬────┘
│
┌────┴─────┐
│是否存在于主记忆体中│
YES └────┬─────┘ NO
┌────────┴─────────┐
│ │
┌───┴────┐ ┌────┴─────┐
│ 从主记忆体读取 │ │ 是否存在于缓冲区中 │
└───┬────┘ YES └────┬─────┘ NO
│ ┌───────┴───────┐
│ ┌───┴─────┐ ┌───────┴──────┐
│ │ 从缓冲区搬移资料 │ │ 对CD-ROM控制器提出读取要求│
│ │ 到主记忆体 │ └──────┬───────┘
│ └───┬─────┘ │
│ │ ┌──────┴────┐
│ │ │现在的碟片存在此资料 │
│ │ YES └────┬──────┘ NO
│ │ ┌────────┴───────┐
│ │┌──┴──┐ ┌───┴┐
│ ││ 从目前的 │ │换片读取│
│ ││ 碟片读取 │ └─┬──┘
│ │└──┬──┘ │
│ │ │ │
│ │ └──────┬───────┘
│ │ ┌────┴───────┐
│ │ │ 资料从碟片读入至缓冲区 │
│ │ └────┬───────┘
│ │ ┌─────┴────────┐
│ │ │资料从缓冲区COPY至主记忆体 │
│ │ └─────┬────────┘
│ │ ┌─────┴───────┐
│ │ │CD-ROM控制器对CPU发出中断,│
│ └────┤通知CPU已完成读取动作! │
│ └─────┬───────┘
│ │
└─────────┬───────────┘
┌─────┴────┐
│CPU完成资料读取动作 │
└──────────┘
这一个流程图实际上还忽略了CD-ROM DRIVER硬体的动作,这才是真正最耗费
时间的地方!
另外这其实不太像TV GAME主机会干的事,这样的检查算起来还是太多,应该是
跳过第一个判断,因为需常驻的资料区及指令区不动,剩下的MAIN MEMORY全部
使用画面处理及声音上,旧资料全部放弃,从CD ROM中读取新资料,自然就不用
检查资料在不在!优点是分配处理画面及声音的MEMORY够大,可以作出超炫CGA
及全程语音,缺点是CD ROM DRIVER的SEEK TIME过慢及BUFFER过小时,等待时
间会很长,又需要利用画面处理的技巧解决及妥善安排档案位置解决!
无论如何你需要知道系统对CD-ROM存取的详细流程,所发出的中断要求,所分
配的MEMORY MAP位置,容量等!
------------------------------------------------------------------------
3.C 其他周边
对于ARCADE系统中,当然还有其他的周边,我建议可以到亚站及巴站的ARCADE
版中,找寻相关的资料!
对于TV GAME系统,所剩下的就是接到TV上了!
[ 第四步 模拟器的运作方式 ]
4.0 模拟器与真实的硬体还是有差距的
姑且不论模拟的像不像,好不好,从执行时的情况看来,真实的硬体是允许平行
处理的,而模拟器却是以循序的方式,轮流使用PC CPU的资源!有很多硬体的机
制是模拟器做不来的,全盘以硬体的角度看模拟器,会发现有很多东东是无法
实作的,单从模拟器的角度看硬体,也会发现文件实在漏掉太多东西!以下的大
部分内容是以解读SNES9X 1.10,MAME 35b5的原始档内容所撰写的,就SFC的硬
体而言,算是满符合上面所分类的项目,除了缺少CD-ROM DRIVER的部份之外,
此外有很多都是我个人的想法,不一定是正确的,这点一定要知道!
------------------------------------------------------------------------
4.1 CPU的处理
当你选定了CPU之后,自然便是需要模拟那个CPU的运行!模拟器的CPU与真实的
CPU有很大的不同,可以分为:
A.CPU CORE:负责解译指令!
B.EXEC_CPU:负责流程控制!
CPU CORE与EXEC_CPU组成了模拟器的核心,CPU与外界的接触及排程由EXEC_CPU
控制,在NMI,SPU,其他装置何时执行,在其余时间再把ROM中的指令交由CPU CORE
解译及执行!执行的流程是由EXEC_CPU检查需不需要执行NMI,SPU,及其他装置
,若需要执行,则执行NMI等相关程式,若不需要执行,则从ROM中抓取指令交由
CPU CORE解译及执行,CPU CORE处理完再交回EXEC_CPU检查需不需要执行NMI,
SPU,及其他装置,直到程式结束为止!
以流程图表示:
┌───┐
│ 开始 │
└─┬─┘
┌──────────→│
│ ↓
│ ┌───────┐ EXEC_CPU
│ │ 取下一个指令 │
│ └───┬───┘ ↓
│ │-----------------
│ ↓ ↑
│ ┌───────┐
│ │ 执行指令 │ CPU CORE
│ └───┬───┘ ↓
│ │-----------------
│ ↓ ↑
│ ┌──┐ ┌────────┐
│ │停止│←┤SHOTDOWN CPU │ EXEC_CPU
│ └──┘ │检查中断 │
│ │行程中断 │
│ │执行或遮掉中断 │<---- 此时模拟器CPU等于
│ └────┬───┘ 处于暂停状况
│ │
└───────────┘
此时模拟器CPU等于又开始执行下一个指令
4.1.0 CPU CORE
CPU CORE的名称应该是指这个程式承继了真正CPU的核心,实际上也是,整个CPU
CORE只保留了暂存器,定址模式,OPCODE的解译及执行(含ALU,CU,IU,OU),PC(
PROGRAM COUNTER,程式计数器)改为整体变数(或EXEC_CPU的区域变数)等,去
除掉所有的中间暂存器(IR,MBR,MAR)!但是因为缺少了时序周期,必须增加另
外一个变数CLOCK_COUNT,当成时序周期来用,并对所有的OP-CODE加上一个会
用掉多少CLOCK的数值,当执行某一个OP-CODE 之后,CLOCK_COUNT必须减掉这
个数值,表示经过了多少个CLOCK!
有许多CPU CORE的作者,同样的也会有不少不同种类的CPU CORE!不同的CPU
CORE效果也大不相同!其中的差别在于:
A.所使用的语言不同:
以组合语言及C语言两种为主,一般以组合语言所写的速度较快!原因是可
以避免掉编译时所产生多余的码,不过实际上还必须评估每个OP-CODE花
多少码模拟,执行将花费多少时间等!
B.对OP-CODE解译的方式不同:
怎么做到有效率的模拟及正确的模拟OP-CODE,一直是CPU CORE作者的目
标,问题是每个人对于OP-CODE的解释不同,实作出来的CPU CORE便会发生
解译不同的情形!这种解译不同的情况,严重时,会导致模拟的效果不正确!
4.1.1 套用现成的CPU CORE :
有现成的CPU CORE 时,当然就是想办法直接套用!要注意套用的程序,例如,必
须先初始化CPU CORE,设定一个定址空间交给CPU CORE等!所以在套用之前,一
定需要先看过说明档,以求了解套用的程序!
4.1.2 自己做一个CPU CORE:
只好自己做一个!做一个CPU CORE模拟器,说难不难,说简单也是骗人!当然一
个简单的方式便是修改别人的CPU CORE的OP-CODE部份,修改成为你心目中认
为的OP-CODE模拟方式!我没有实际做一个CPU CORE模拟器的经验,只能有观
察别人的模拟器中提供一些经验!
需要提供几个重要的函式,这是CPU CORE的外观:
A.RESET_CPU(INITIAL_CPU):
把CPU CORE的状态恢复至初始时的状态!各暂存器,旗标,程式计数器!
B.CPU_SHUTDOWN:
释放CPU CORE所占用的记忆体!
C.OP-CODE DECODER&EXECUTOR:
解译并执行OPCODE的程式!写法很多,CASE-SWITCH,或是函式阵列等!不管
是CASE-SWITCH或是函式阵列都是利用转译前OP-CODE的十六进位数值当
成判断的依据!
就结构上来说,需要实作出这是CPU CORE的内在:
A.CPU的暂存器,旗标等!你可以直接定义一个CPU的结构,这样应用上较为便
利!
B.CPU的定址模式!直接定址指令为何,间接定址指令如何处理等!
C.CPU所用的每个OP-CODE,实作的方式满多的,需要ALU的OP-CODE直接用四
则运算代替等!你必须要先知道这个CPU提供多少种OP-CODE,每个OP-CODE
的运作方式,OP-CODE如何解码等,再一一实作出每个OP-CODE来!
我目前的程度,只能提供意见到这里!
4.1.3 MULTI-PROCCESSOR的场合:
面对多处理机的系统时,不可避免的问题就是:
A.必须实作出好几个CPU!
B.必须实作CPU的沟通方式!
对于问题A而言,可以以定义出CPU结构再宣告多个CPU结构当成有多个CPU,而
CPU CORE共用同一份!对于问题B而言,如果是MASTER/SLAVE系统,就是在
MASTER CPU的EXEC_CPU中多实作出处理SLAVE CPU中断及其他沟通的方式等!
4.1.4 CPU与其他周边沟通方式的处理
简单的说,就是处理中断的方式!真实的硬体是可以平行运作的,但是模拟器可
不行,至少在没办法写成几乎可平行运作又可相互沟通的执行绪前不行!由前
面的流程图可以发现,必须在EXEC_CPU中排入中断检查,中断执行,和一切周边
状态检查及更新的程式片段!整理一下,包括:
A.SPU状态的检查:
SPU状态的检查在整个模拟器占了很重要的地位,因为声音不能有任何中
断现象,所以几乎在每个函式都必须执行一次,在较长的函式中甚至必须
执行许多次,以确保声音不会中断!
B.摇杆状态检查:
检查摇杆按键是否有按下的讯息传来!
C.NMI中断检查:
检查是否有NMI中断发生,依其优先顺序执行!
D.一般中断检查:
检查是否有中断发生,依其优先顺序执行!
E.PPU定期资料更新:
简单的说就是画面的更新!前面CPU CORE段落中说到必须将每个OP-CODE
加上一个用掉多少CLOCK TIME的常数,在把PPU定期资料更新周期定义成
多少个CLOCK COUNT,每执行一个OP-CODE就扣掉一些,等到变成负数或等
于零时,就表示定期资料更新周期到了,就去执行资料更新的函式!这就
是没有时序产生器以产生时序的变通方法!
F.SPU定期资料更新:
若SPU中含有TIMER,则必须于一定时间时更新状态!这可保持整个模拟器
以一定的时序同步执行,因为有些装置是需要同步执行的!这个TIMER的
计算方式是以相对于多少CPU CLOCK TIME或是以相对于多少CLOCK COUNT
来计算!
4.1.5 DSP的处理
实际上有两种类型的DSP,这两种在处理有很大的分别:
A.模拟这个DSP的外在行为:
模拟时需要做一个DSP的结构与CPU沟通,但是实际上的内部执行只是呼叫
函式而已!例如给DSP算一个COS值等!这是模拟这个DSP的外在行为就可以
了!
B.模拟这个DSP的内在行为:
最明显的例子就是SFC的SuperFX晶片,这其实是一个RISC的处理器,必须
模拟出这个处理器的内在行为,OP-CODE等,就像模拟一个CPU一样!
------------------------------------------------------------------------
4.2 MEMORY MAP的处理
简单的说,就是配置所需的记忆体,包含ROM,RAM,SRAM,VRAM(PPU用)等!并载入
至对应的区域内!同时在模拟器结束时必须释放出所配置的记忆体!需要实作
出:
A.INIT MEMORY MAP:
也就是初始化MEMORY MAP,对ROM,RAM,SRAM,VRAM(PPU用)都配置足够大的
记忆体!不过倒是不需要只配置一大块记忆体当成整个MEMORY MAP,分成
RAM区,SRAM区,ROM区也可以,但是存取时必须视为一整块MEMORY MAP!另
外还有一些需要配置的记忆体区块,也能在此一同处理!
B.FREE MEMORY MAP:
在模拟器结束时,必须释放出原来配置的记忆体,在这个函式中处理!
C.LOAD ROM IMAGE FILE:
档案处理的部份不在这边做,这里直接用档案指标参数操作!把档案内容
搬移到MEMORY MAP中分配给ROM的区域!一般而言,除了CD-ROM之外,都是
配置出足够的大小,很明显的,如果ROM IMAGE有50MBYTE,就需要配置出
50MBYTE!这里需要注意一下,有些系统的ROM区域是分段的,LOW ROM&HIGH
ROM,也需特别处理!
D.LOAD/SAVE SRAM FILE:
与LOAD ROM IMAGE FILE处理的方式一样!比较不一样的是,SRAM FILE要
随时准备存取,ROM IMAGE FILE一般只有在更换游戏时才会更动!
E.LOAD SYSTEM ROM FILE:
与LOAD ROM IMAGE FILE处理的方式一样!
F.FIX ROM SPEED:
有时候,会需要模拟ROM存取的速度!
G.特殊晶片的ROM IMAGE处理:
有些晶片或是PPU,SPU会有用到专用的ROM,原则上仍然等同LOAD ROM
IMAGE FILE的方式处理!
这里提供的还是原则性的写法,详细的内容,还是得多看看别人的处理方法!
4.3 PPU的处理
4.3.0 PPU的处理
在大部分的情况而言,通常都不会知道PPU是什么晶片,所用的OP-CODE等,也找
不到相关的资料,通常找到的是CPU透过MEMORY MAP的窗口与PPU沟通的资料,
所以模拟的方式一般都是模拟外在的行为,而不是模拟内在的操作情形!无论
如何,需要提供:
A.RESET PPU(INIT PPU):
重新把每个MEMORY MAP所对应的功能的参数,恢复成初始的状态!
B.CPU设定PPU的函式:
也就是处理那些MEMORY MAP的功能的函式!与CPU的OP-CODE不太一样,这
里较常用CASE-SWITCH的结构!原因是速度较快吧!以MEMORY MAP所分配的
"位址"当成SWITCH的判断依据!
C.CPU读取PPU处理后状态的函式:
也就是处理完那些MEMORY MAP的功能之后,预备由CPU读取的函式!也是使
用CASE-SWITCH的结构!这里不一样的地方是,并不是每个功能都有传回资
料,某些CASE的处理就可直接跳过!也是以MEMORY MAP所分配的"位址"当
成SWITCH的判断依据!
不过这都只是外观而已,真正的还是模拟每个功能的程式,一般找得到的资料
会像这个样子,以SNES9X为例:
SNES Documentation v2.30: Written by Yoshi
----------------------------------------------------------------------------
|rwd2?|Address|Title & Explanation |
||||||-----------------------------------------------------------------------|
|||||| |
||||||__ ?: Don't know what the statistics on this register are |
|||||____ 2: 2 byte (1 word) length register |
||||_____ d: Double-byte write required when writing to this register |
|||______ w: Writable register |
||_______ r: Readable register |
| |
|Words in brackets ( [] ) are the official "names" of the registers |
|Words in braces ( {} ) are different from the "real" SNES manual |
|Bits define 1 as "ON/ENABLE" and 0 as "OFF/DISABLE," unless otherwise stated|
|Registers without any bits/defined-data can be assumed to be 8 bits in size |
|and should only be read once. |
----------------------------------------------------------------------------
|rwd2?|Address|Title & Explanation |
|----------------------------------------------------------------------------|
| w |$2100 |Screen display register [INIDISP] |
| | |x000bbbb x: 0 = Screen on. |
| | | 1 = Screen off. |
| | | bbbb: Brightness ($0-$F). |
| | | |
| | | |
----------------------------------------------------------------------------
按照说明写成对应的程式:
========================================================================
case 0x2100:
// Brightness and screen blank bit
if (Byte != Memory.FillRAM [0x2100])
{
FLUSH_REDRAW ();
if (PPU.Brightness != (Byte & 0xF))
{
IPPU.ColorsChanged = TRUE;
PPU.Brightness = Byte & 0xF;
S9xFixColourBrightness ();
if (PPU.Brightness > IPPU.MaxBrightness)
IPPU.MaxBrightness = PPU.Brightness;
}
if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80))
{
IPPU.ColorsChanged = TRUE;
PPU.ForcedBlanking = (Byte >> 7) & 1;
}
}
break;
========================================================================
关于如何写才算完美,对不起,我没有办法说明!而实际上,这就是一个模拟器
好坏的差别!
需要补充的是,通常在CPU设定PPU的函式中会把像SPU,DMA等同样使用CASE-
SWITCH结构的函式放在同一个CASE-SWITCH结构中!只是执行的函式本体另外
写而已!
4.3.1 实际绘图的动作:
上面拉拉杂杂一堆,就整个PPU而言,仍然只是外观而已!只是设定PPU去做某一
件事,设定它的参数,你还是得实作出真正绘图的动作!这里还是受限于我的知
识不足,等到以后再补充!另外,需要做一个初始动作的函式,这是处理PPU内部
的初始化!
4.3.2 SCREEN REFRESH
SCREEN REFRESH有两种:
A.模拟硬体处理SCREEN REFRESH的动作:
这里还是受限于我的知识不足,等到以后再补充!
B.实际显示出画面于MONITOR上:
这里还是受限于我的知识不足,等到以后再补充!
------------------------------------------------------------------------
4.4 SPU运作方式:
4.4.0 SPU(图形处理单元)的功能及地位:
4.4.1 SPU的组成:
4.4.2 与PPU的不同处:
4.4.3 声音处理器专用DSP的功能:
4.4.4 声音处理器的指令:
------------------------------------------------------------------------
4.5 摇杆控制装置及钱币计数器等NMI的处理
4.5.0 MEMORY MAP中处理摇杆控制装置的方式:
除了一些特殊控制器之外,摇杆上的每个按键或是方向键都是用1BIT表示其状
况--按下或是没按下!直接由MEMORY MAP所分配的位址下手,但是因为PC上可
拿来控制的装置太多了,需要一个中间程式转换,大致如下:
┌───┐┌───┐
│键盘 ├┤DRIVER├┐ MEMORY MAP所分配的位址
├───┤├───┤│ ┌───┐
│滑鼠 ├┤DRIVER├┤ │ │
├───┤├───┤│┌────┐├───┤ ┌────┐
│摇杆1 ├┤DRIVER├┼┤转换程式├┤ PAD ├─┤EXEC_CPU│
├───┤├───┤│└────┘├───┤ └────┘
│摇杆2 ├┤DRIVER├┤ │ │
├───┤├───┤│ │ │
│摇杆3 ├┤DRIVER├┘ └───┘
└───┘└───┘
摇杆?表示
另一种摇杆,不是另一只
这样画是稍微不正确,不过讲解很方便!要加入一种新的装置,就需要有专用的
DRIVER才能支援到!所谓专用的DRIVER是指如何读取讯号,怎样解读所得到的
讯号是什么意义,负责这种工作的程式,一些特殊的指向装置都会提供专用的
开发工具,这些开发工具便会提供如何解读所得到的讯号,其实这就是我所指
的DRIVER!DRIVER是对应WINDOWS的说法!摇杆的动作不正常,乱跳啦,不支援某
种摇杆啦,就是DRIVER层级的问题!重新对应所按的按键,或是选择不同的装置
输入讯号,就是转换程式的问题!控制装置所找到的DRIVER不同的话,支援的情
况就有很大的差别!就WINDOWS模拟器而言,比较新的通常都使用DIRECT X的
DIRECT INPUT支援不同的指向装置,这样非常方便,只要符合DIRECT INPUT的
函式呼叫,就通用所有指向装置!但是DOS模拟器并没有这么简单,必须一种一
种的支援!
另外我把指向装置切换及按键重定义视作转换程式!转换程式的目的在于适当
的把所选择的指向装置上所按的按键转换成所模拟TV GAME主机的按键资讯字
组!很明显的,具有三种功能:
1.选择所支援的指向装置!
2.可自由定义所选择的指向装置上的按键对应所模拟主机上的按键!
3.转换所选择的指向装置上的按键定义成为所模拟主机使用的资讯!
不过其实还有第四种功能:
4.热键(HOT KEY)处理界面!
转换程式一般都是利用CASE-SWITCH结构设计,不论是处理何种指向装置的DRIVER
提供的讯息!而K/B的所使用的CASE-SWITCH结构,还可以加入热键处理,例如呼
叫GUI,RESET,FRAMESKIP,抓图,当然还有EXIT--退出模拟器,处理方式就是增
加CASE,当KB有按键按下时,属于模拟器摇杆的部份就组合成正确的字组填入
MEMORY MAP的位址,其他的则检查是否属于热键,是则执行对应的热键处理函
式,再不属于热键的就直接忽略掉!
不管是什么指向装置,到了转换程式最后都会变成所模拟主机的按键资讯字组
!然后设定一个中断FLAG,等到模拟器控制权又回到EXEC_CPU时,将会检查这个
中断FLAG,再读取这个按键资讯字组,然后CPU CORE会根据这个字组,执行ROM
中的程式!
4.5.1 特殊指向装置的处理:
下次再写!
4.5.2 钱币计数器,START键等NMI的处理:
不管是何种NMI,都是设定一个中断FLAG,等到模拟器控制权又回到EXEC_CPU时
,将会检查这个中断FLAG,再读取这个按键资讯字组,然后CPU CORE会根据这个
字组,执行中断服务常式或ROM中的程式!
------------------------------------------------------------------------
4.6 RESET处理
算起来这个最简单,把所有相关的初始函式,全部关在一起呼叫一次,就是RESET
了!如果要处理一些特殊动作,也是在这里处理,当所有初始函式执行完成之后
,再执行想要做初期奇怪动作的函式!这个功能的呼叫方式通常是设置在按键
读入的处理函式中,在CASE-SWITCH结构中,多一个CASE处理RESET!
------------------------------------------------------------------------
4.7 DIP SWITCH作用处理方式:
这个也是满简单的,设计一个以位元操作的方式定义出DIP SWITCH的结构,最
好是附以显而易见的定义,最后是设计一个专门处理设定DIP SWITCH功能的函
式,有专用的画面及控制方式等!比较懒的方式是,让使用者自己计算出要设定
DIP SWITCH功能的十六进位数值,模拟器只要读入这个数值即可!这个功能的
呼叫方式通常是设置在按键读入的处理函式中,在CASE-SWITCH结构中,多一个
CASE处理DIP SWITCH!
------------------------------------------------------------------------
4.8 DMA CONTROLLER运作处理方式
模拟器是不可能会有DMA这种机制的,当DMA功能启动时,实际执行时是从EXEC_CPU
函式中直接转移到DMA控制函式,进行字组的搬移,但是要定时或完成一个动作
时,需要模拟DMA CONTROLLER对CPU发出中断的动作,这个动作就是整个DMA函
式的核心,而资料搬移动作反而是最不重要的,因为这个动作就是资料搬移的
动作:
TARGET_MEM = SOURCE_MEM;
还有一个动作要处理,就是CLOCK TIME的动作,不论DMA多快,都不可能在不经
过任何CLOCK TIME就能完成,我们需要模拟CLOCK TIME经过的动作!
你会发现EXEC_CPU转移到DMA控制函式时,整个模拟器CPU是处于暂停的状态,
这也是符合DMA运作的机制!
前面都是DMA CORTROLLER的内部机制:
A.模拟DMA CONTROLLER对CPU发出中断的动作!
B.资料搬移动作!
C.模拟CLOCK TIME经过的动作
还必须提供CPU使用DMA的机制,CPU对DMA CONTROLLER的控制方式还是以MEMORY
MAP中分配给DMA CONTROLLER的窗口设定DMA CONTROLLER的参数,在DMA
CONTROLLER动作时便按照这些参数运作,需要实作出以下的函式:
A.RESET_DMA:
恢复DMA CONTROLLER成初始状态!
B.DMA 传输模式:
必须提供所使用DMA的所有传输模式!CYCLE STEALING就是搬移一个字组
就把控制权交回EXEC_CPU,BURST MODE除了资料搬移外,还需要处理经过
多少CLOCK TIME!
------------------------------------------------------------------------
4.9 光碟机装置存取方式:
有空再写!
------------------------------------------------------------------------
4.A 档案处理:
4.A.0 档案载入
有空再写!
4.A.1 LOAD HISCORE FILE
有空再写!
4.C.2 LOAD/SAVE 随时记忆档
有空再写!
------------------------------------------------------------------------
4.B 特殊功能:
4.B.0 抓图
有空再写!
4.A.1 抓音乐档
有空再写!
4.B.2 GUI
有空再写!
4.B.3 CHEAT CODE
有空再写!
4.B.4 CHEAT TOOL
有空再写!
4.B.5 DISASM
有空再写!
------------------------------------------------------------------------
4.C 可携性版本,WINDOWS版本,更先进的模拟器架构
有空再写!
4.C.0 可携性的研究
有空再写!
4.C.1 WINDOWS版本
有空再写!
4.C.2 更先进的模拟器架构
有空再写!
[ 第一步之前的那一步! ]
[ 第一步 - 收集资料 ]
1.0 你有什么?
1.1 别人有什么?
[ 第二步 - 整理所获得的资料 ]
[ 第三步 TVGAME 硬体的运作方式 ]
3.1 硬体周边分类
3.2 CPU及MEMORY MAP
3.2.0 CPU的功能与地位
3.2.1 MULTI-PROCESSOR的系统:
3.2.2 看起来不一样,实际又是大同小异的CPU
3.2.3 MEMORY MAP的功能
3.2.4 ROM IMAGE
3.2.5 CPU与其他周边沟通方式
3.2.6 DSP的功能
3.3 PPU(图形处理单元运作)方式
3.3.0 PPU(图形处理单元)的功能及地位
3.3.1 PPU的组成
3.3.2 VBLANK & HBLANK
3.4 SPU(声音处理单元)运作方式:
3.4.0 SPU(图形处理单元)的功能及地位:
3.4.1 SPU的组成:
3.4.2 与PPU的不同处:
3.4.3 声音处理器专用DSP的功能:
3.4.4 声音处理器的指令:
3.5 ROM & RAM AREA
3.5.0 SYSTEM ROM:
3.5.1 没有SYSTEM ROM的基版:
3.5.2 GAME ROM
3.5.3 以光碟做媒介的ROM -- CD ROM:
3.5.4 GAME ROM的MAPPER 问题:
3.5.5 如何开发游戏:
3.5.6 ROM中的程式如何控制硬体:
3.6 摇杆控制装置及钱币计数器等NMI的处理
3.6.0 摇杆通知CPU有按键按下的原理:
3.6.1 MEMORY MAP中分配给摇杆控制装置的方式:
3.6.2 钱币计数器,START键等NMI的处理:
3.6.3 非数位式摇杆的输入:
3.6.4 钱币计数器,START键等NMI的处理:
3.7 RESET处理
3.7.0 加入RESET的原因:
3.7.1 RESET的流程:
3.8 DIP SWITCH
3.8.0 加入DIP SWITCH的原因:
3.8.1 DIP SWITCH的作用方式:
3.9 BACKUP DEVICE
3.9.0 需要BACKUP DEVICE的原因:
3.9.1 存取BACKUP DEVICE的方式:
3.A DMA CONTROLLER
3.A.0 什么是DMA(DIRECT MEMORY ACCESS) CONTROLLER?
3.A.1 DMA的运作方式:
3.B 光碟机装置
3.B.0 使用CD-ROM DRIVER的原因:
3.B.1 CD-ROM的存取方式:
3.C 其他周边
[ 第四步 模拟器的运作方式 ]
4.0 模拟器与真实的硬体还是有差距的
4.1 CPU的处理
4.1.0 CPU CORE
4.1.1 套用现成的CPU CORE :
4.1.2 自己做一个CPU CORE:
4.1.3 MULTI-PROCCESSOR的场合:
4.1.4 CPU与其他周边沟通方式的处理
4.1.5 DSP的处理
4.2 MEMORY MAP的处理
4.3 PPU的处理
4.3.0 PPU的处理
4.3.1 实际绘图的动作:
4.3.2 SCREEN REFRESH
4.4 SPU运作方式:
4.5 摇杆控制装置及钱币计数器等NMI的处理
4.5.0 MEMORY MAP中处理摇杆控制装置的方式:
4.5.1 特殊指向装置的处理:
4.5.2 钱币计数器,START键等NMI的处理:
4.6 RESET处理
4.7 DIP SWITCH作用处理方式:
4.8 DMA CONTROLLER运作处理方式
4.9 光碟机装置存取方式:
4.A 档案处理:
4.A.0 档案载入
4.A.1 LOAD HISCORE FILE
4.C.2 LOAD/SAVE 随时记忆档
4.B 特殊功能:
4.B.0 抓图
4.A.1 抓音乐档
4.B.2 GUI
4.B.3 CHEAT CODE
4.B.4 CHEAT TOOL
4.B.5 DISASM
4.C 可携性版本,WINDOWS版本,更先进的模拟器架构
4.C.0 可携性的研究
4.C.1 WINDOWS版本
4.C.2 更先进的模拟器架构
[ 第五步 如何偷别人的程式及与别人交换意见 ]
5.0 如何偷别人的程式
5.0.0 模仿是进步最快的方式:
5.0.1 哪里找得到模拟器原始码?
5.0.2 看得懂别人的程式也不是件容易的事:
5.1 和别人交换意见:
[ 第六步 实际撰写一个模拟器 ]
[ 第七步 测试,除错及版本更新 ]
7.0 测试与除错是一条漫长的道路:
7.1 自己测试的盲点:
7.2 版本更新:
7.3 最少保留一份每一个版本的原始档及执行档:
[ 第八步 撰写说明文件 ]
[ 第九步 公开你的版本 ]
9.0 建立个人网页:
9.1 投稿至模拟器新闻性网页!
[ 后记 ]
[ 常用名词解释 ]
------------------------------------------------------------------------
[ 第一步之前的那一步! ]
为什么你想做一个模拟器?练习程式语言?还是你想玩很难玩到的游戏?还是你只
是单纯的想做一个模拟器?动机会影响你的热衷度,同时你也必须选定一个明确
的目标,模拟一个ARCADE的游戏,还是游戏主机?一旦选定了明确的目标,你一定
要下定决心,否则便没有完成这个模拟器的机会!在撰写模拟器时,你会遇到很多
困难,像找不到资料;为了除错,几天都很难睡觉!就算是写好了,放出来也还有一
堆莫名其妙的人抱怨一些有的没的!你唯一的报酬可能就只有成就感而已,或者
加上能玩到已经玩不到的游戏.如果你还愿意去写一个模拟器,我真的十分佩服
你!
------------------------------------------------------------------------
[ 第一步 - 收集资料 ]
1.0 你有什么?
在你想写模拟器之前,你必须要真实的检视你自己的资源,你会什么程式语言?
你对所模拟的硬体认识多少?你了解计算机内部运作的方式吗?你看不看得懂硬
体线路图?这些会影响你写不写得出一个完整的模拟器!其实程式语言的影响
也不是那么严重,还是有人可以用QUICK BASIC写出模拟器,只是效率实在不好
而已,但是其他的因素却是影响这个模拟器写不写的出来!
1.1 别人有什么?
你需要去找你想要模拟的硬体的资料,你有哪些要找的呢?
A.使用何种CPU?基版上面有多少特殊的晶片?时序速度多少?有多少相关资料?
B.有没有硬体概图(Schematics)?有没有DIP SWITCH的资料?
C.有没有MEMORY MAP?有没有软体的其他相关资料?
D.有没有别人已经写好的模拟器原始档?
你可到哪里找?
A.新闻讨论区!
B.模拟器网页的留言版!
C.模拟器新闻网页-可以知道是否有模拟器提供其原始档!
D.模拟器程式发展资源网页-可以收集到许多前人写好的文件!
E.别人的模拟器网页-也许有额外的连结可以让你找到多一点资讯!
F.如果是游戏主机,到官方网页也许有意想不到的资料!
还缺了什么?
A.CPU 手册,反组译工具!
B.也许你会需要电子元件手册,供你分别或查询元件的用途及接脚定义等!
C.适当的程式语言,适当的函式库(节省开发时间)!
------------------------------------------------------------------------
[ 第二步 - 整理所获得的资料 ]
在搜集到所有能收集的资料之后,依照我们要的部份加以分类:
硬体:
A.CPU种类&速度!次系统处理器种类&速度!
B.Schematics,DIP SWITCH,硬体线路,电路图等!
C.MEMORY MAP,摇杆接脚定义!
D.基版上的SYSTEM ROM!
E.特殊晶片的设计资料!例如图形处理晶片,声音处理晶片等!
F.画面处理的方式,图形及声音编码方式等!
软体:
A.CPU手册,反组译工具,CPU模拟程式等!
B.游戏ROM!SYSTEM ROM!
C.特殊晶片的模拟程式!
D.别人的模拟器程式,可以"偷"或是看看别人的写法!
E.函式库手册等!
------------------------------------------------------------------------
[ 第三步 TVGAME 硬体的运作方式 ]
3.1 硬体周边分类
一般说来,你可以把整个TVGAME硬体分为:
A.CPU:
一般是廉价的泛用处理器,例如68000,6502,Z80等!用来指挥整个硬体的
运作!复杂的系统甚至以多处理机协同处理!例如TAITO的双68000系统,SS
的双SH-2系统!
B.PPU(图形处理单元,VDP,GPU):
专职于图形的处理!包含PICTURE PROCCESSOR,专用RAM,专用ROM,数位类
比转换器等!常见名称的有PPU(PICTURE PROCCESS UNIT),GPU(GRAGHIX
PROCESS UNIT),VDP(VIDEO DATA PROCCESSOR),以下都使用PPU代替!
C.特殊DSP晶片
一种能快速计算数值的晶片,用来协助处理资料!
D.SPU(声音处理单元,APU):
专职于声音的处理!包含SOUND PROCCESSOR,专用RAM,专用ROM,专用DSP,
声音晶片,数位类比转换器等!名称也很多,SPU(SOUND PROCCESS UNIT),
APU(AUDIO PROCEESS UNIT ),以下用SPU代替!
E.ROM AREA:储放ROM的区域!
1.SYSTEM ROM:
类似于PC 中BIOS+OS的地位,提供开机检查,常用函式等!
2.GAME ROM:
真正游戏的程式区域!家用主机把图形,声音,及其他资料储放在一起!
但是ARCADE游戏通常会分开储放!如果细分的话,可以分为:
a.GRAPHIC ROM:储放游戏图形资料!
b.SOUND ROM:储放声音资料!
3.储放其他资料的ROM!
F.MAIN MEMORY,WORK RAM
就是主记忆体!
G.光碟机及控制周边!
只有以光碟作为储存媒介的主机才有!
H.摇杆等控制装置:
摇杆输入,RESET,钱币计数器等!
I.BACKUP DEVICE:
电池记忆,记忆卡之类的装置!
J.基版控制周边,DMA装置,外部扩充界面及装置等!
K.硬体其他周边,萤幕,电源供应器等!
当然也不是每一个TVGAME系统都这么完整,越早期的家用主机或ARCADE基版就
简单一点!现在的家用主机或是ARCADE 系统基版就十分复杂,这都是你在搜集
资料时一定要找到的,有些是模拟器一定会用到的,甚至影响模拟器的完成度,
有些则是模拟器可省略的,例如萤幕,电源供应器等!以下对于会使用在模拟器
上的装置作一下说明!
------------------------------------------------------------------------
3.2 CPU及MEMORY MAP:
3.2.0 CPU的功能与地位:
对整个TVGAME或是ARCADE来说,CPU应该算是"导演"的工作,而ROM IMAGE则是
导演手上的剧本,用来指挥周边的动作.指挥别人,当然可以不用太高级,只要
足够就行了!画面表现的好坏,声音处理的好不好,与CPU的关系较少!但是如果
周边的处理比CPU快太多,让周边老是等待也不好,同时,有一部份工作也必须
由CPU处理,所以CPU也不可能太慢!把价格与运算能力做考量依据,才选出适用
的CPU!常见的有68000,6502,Z80等!
3.2.1 MULTI-PROCESSOR的系统:
MULTI-PROCESSOR的系统就是指这个系统中含有两个以上的CPU,例如SS就是由
两个SH-2所组成的,依照CPU分工的不同,可以分为:
A.MASTER/SLAVE(非对称结构):
只有一个CPU(MASTER)负责IO的工作,计算的工作则每个CPU都能执行!同
时只有MASTER CPU能执型O.S.,而SLAVE CPU则是以中断要求MASTER的服
务!
B.SEPERATE EXECUTIVES:
每个CPU有自己的OS,INTERRUPTS,CPU种类及OS种类均允许不同,不能共同
处理同一工作!
C.SYMMETRIC ORGANIZATION:
由一个OS整合管理所有的处理机,称为PROCESSOR POOL,每个CPU皆能存取
任一I/O DEVICE及储存单元!
如果你想做的是MULTI-PROCESSOR的系统,必须要先搜集CPU间的关系,沟通方
式,例如SS就是一个MASTER/SLAVE的系统!
3.2.2 MEMORY MAP的功能:
正如家家都必须要有不同的地址,才能把邮件送到正确的地方,CPU也需要相同
的机制,用来存取到正确的资料,处理机所使用的方式是加上位址线,连接至位
址汇流排,再连接至RAM,ROM,其他装置等!位址汇流排宽度决定了CPU所能定址
的最大空间,这空间,你可称为"定址空间"!实际上不同的定址模式会影响定址
空间,不过这里我们就假装不知道吧!
为了存取方便,需要将定址空间做一番规划,规划之后的定址空间,称之为MEMORY
MAP!把定址空间分成一段一段的,把每一段都赋予不同的用途!例如下面是SFC的
MEMORY MAP!
SNES Documentation v2.30: Written by Yoshi
----------------------------------------------------------------------------
|Here's a really basic memory map of the SNES's memory. Thanks to Geggin of |
|Censor for supplying this. Reminder: this is a memory map in MODE 20. |
|----------------------------------------------------------------------------|
|Bank |Address |Description |
|-------|--------------|-----------------------------------------------------|
|$00-$3F|$0000-$1FFF |Scratchpad RAM. Set D-reg here if you'd like (I do) |
| |$2000-$5FFF |Reserved (PPU, DMA) |
| |$6000-$7FFF |Expand (???) |
| |$8000-$FFFF |ROM (for code, graphics, etc.) |
|$70 |$0000-$7FFF |SRAM (BRAM) - Battery RAM |
|$7E |$0000-$1FFF |Scratchpad RAM (same as bank $00 to $3F) |
| |$2000-$FFFF |RAM (for music, or whatever) |
|$7F |$0000-$FFFF |RAM (for whatever) |
----------------------------------------------------------------------------
不只是TVGAME及ARCADE,IBM PC也有同样的机制,例如DOS的0KB-640KB-1024KB
规划!
3.2.3 看起来不一样,实际又是大同小异的CPU:
这里先暂且搁下MEMORY MAP不谈!回到CPU,如果你有机会看到SNK NEOGEO/MVS
系统的基版的话,从文件上知道,它应该是MOTOROLA 68000的CPU,不过你就是找
不到长方形的MOTOROLA 68000 CPU,因为SNK特别订制这颗CPU,把68000及两个
PPU作在一起,成为一颗VLSI!实际上,有很多机器都是以这样的方式制作,订制
成VLSI!在写模拟器时,只需要知道它的解码方式等同于MOTOROLA 68000 CPU
就可以了!
还有一种形式是DECODE及执行结果等同于其他CPU,最明显的例子就是FC用的"
65C02",事实上它与真正的6502不太一样,只是编码及执行结果等同于6502!在
写模拟器时,仍然需要知道它的解码方式等同于6502就行了!
3.2.4 ROM IMAGE:
一般TVGAME及ARCADE游戏,都是把程式或资料烧录在ROM中-不论是ROM IC颗粒
,还是CD-ROM!很明显的,除了CD-ROM之外,没有办法直接读取其中的指令或资
料(即便是CD-ROM也可能自己搞奇怪格式,所以也可能无法读取),所以需要使
用ROM DUMPER,把ROM中的指令或资料DUMP成二进位制档案,称为"ROM IMAGE"!
因为所使用的机器语言不同(或者粗略的称为CPU不同),ROM IMAGE的内容目前
对PC并不具任何意义,所能做的也只局限在COPY,MOVE,EDIT HEX,或是ZIP起来
,类似于图形档的处理,即便它是一个受欢迎的游戏!直到有适用的模拟器出现
,ROM IMAGE才有价值--拿来玩游戏!把ROM做成ROM IMAGE,在大部分情况下都
算是比较简单,所以ROM IMAGE多,而对应的模拟器少,作ROM IMAGE只要有机器
就行,但是没人写模拟器就是白搭!
回到ROM IC上,ROM上烧录的当然是程式或资料,问题是给谁的资料!如果不考
虑有些基版有SYSTEM ROM的情况(留待SYSTEM ROM区再讨论)!ROM一般都是给
CPU的资料,所以指令都是CPU的机器语言,存取到资料区时,即便可能是给另外
PPU或SPU所使用的指令,对于CPU而言,这些仍然视作"资料"而不是"指令"!等
到这些"资料"传递给对应PPU或SPU时,才会变成"指令"!
3.2.5 CPU与其他周边沟通方式:
这里必须要先解释"MEMORY MAPPED I/O"!所谓MEMORY MAPPED I/O"是指I/O界
面位址和记忆体位址使用相同的位址空间,此时界面暂存器是记忆体系统的一
部份!界面单元和记忆体使用相同指令存取,资料位址指到记忆体,即是和记忆
体沟通;如果指到界面暂存器位址范围即是要进行I/O动作!
大部份的TVGAME及ARCADE都是设计成MEMORY MAPPED I/O,以这种方式对其周
边作存取动作,所以知道你所要模拟的系统的MEMORY MAP是很重要的事!尤其
是对PPU,SPU的存取(设定执行某一特定功能,或传递图形或声音资料),知道
细部的MEMORY MAP结构,及每个BIT的用途,才能正确的模拟出PPU,SPU的功能!
在MEMORY MAP中,属于PPU,SPU功能的段落的位址上的字组中,每一个BYTE上的
每一个BIT都有特定的用途,这些就是CPU与周边沟通的窗口!CPU把设定好的资
料,写入到正确的位址,就等于是叫PPU,SPU执行某一个特定的功能!详细的执
行这些功能的时机,我没有找到资料!比较可能执行时机可能为两种,一是CPU
直接中断PPU,SPU,然后PPU,SPU检查这些窗口,执行对应的功能!一是PPU,SPU
在定期中断CPU时,同时检查这些窗口,再执行对应的功能!不过写成模拟器时,
都是在CPU暂停的期间,PPU,SPU再去检查这些窗口,执行对应的功能!
3.2.6 DSP的功能
在大部分的情况下,CPU不需要处理大量的数字资料,所以在选择CPU时,一般并
不刻意挑选数值处理速度极快而高价的CPU,而是在CPU之外,另外搭配高速的
DSP,协助CPU处理数值资料,类似于PC上的FPU,当然PC现在都是内建的,在386
及486SX的时代,FPU是选购项目!在特殊的情况下,DSP是属于可加入式的,例如
SFC便是可在卡匣上加装DSP协助CPU处理大量多边型的运算,而不是固定在基
版上,因为它并不是必要的!不过因为需要处理的资料越来越多,新一代的TV
GAME及ARCADE系统都内建了DSP,以免数值资料处理过慢,拖累整个执行速度!
在你找资料时,也必须找到CPU与DSP沟通的方式,DSP如何处理资料,以模拟出
DSP的功能!
------------------------------------------------------------------------
3.3 PPU(图形处理单元运作)方式:
3.3.0 PPU(图形处理单元)的功能及地位:
PPU是整个TV GAME/ARCADE系统的重心,游戏画面能做到多炫,特效多少,完全
都是由PPU去表现!而CPU只是负责指挥的工作,所以使用同一个CPU的系统,如
果所使用的PPU能力不同的话,所呈现的效果也将有很大的不同!这是模拟器所
要模拟的重心,整个模拟器完成度几乎全取决于PPU及SPU是否能模拟的完美!
3.3.1 PPU的组成:
包含PICTURE PROCCESSOR,专用RAM,专用ROM,数位类比转换器等!简图如下:
PPU
┌───┐ +---------------------------+
├───┤ | ┌───┐ |
│DATA ├─┬──────┬─┬┤RAM │ |
├───┤┌┴─┐| ┌─┴┐││(VRAM)│ |
│ ││CPU ├──┤PP ││├───┤ |
│ ││ │| │ │├┤ROM │ |
│ │└──┘| └──┘││ │ |
│ │ | │├───┤ |
└───┘ | ││DAC │ |
ROM&RAM | └┤ ├──── VIDEO OUT
| └───┘ |
+---------------------------+
CPU透过MEMORY MAP中的各个窗口,与PP(图形处理器,PICTURE PROCCESSOR)沟
通并设定欲执行的功能!PP便到从ROM&RAM中搬移所要处理的资料到自己的RAM
中!接下来是功能解码,再从ROM中找出应该执行的指令,依序执行之后,写回RAM
,待萤幕更新周期时,由DAC(数位-类比转换器)转换成MONITOR能接受的讯号,
显示到萤幕!
3.3.2 VBLANK & HBLANK:
由于萤幕(MONITOR)的更新是由电子束打在对应的点,让点上的萤光质发光,藉
以显示出要显示的图形!电子束打的方式是一个接着一个,由左至右,由上至下
,因为视觉暂留的现象,人眼看到的就是整个萤幕的图形!电子束从每一行的最
右边回到下一行的最左边,这一段时间称为H-BLANK,水平空白期!同样的,电子
束会从右下角再回到左上角,准备做下一次整个萤幕的更新,这一段时间称为
V-BLANK,垂直空白期!HBLANK与VBLANK的时间长短与移动的距离有关,行移动
的HBLANK时间较短,而VBLANK的时间较长,所以PPU使用VBALNK时间做一些工作
是很重要的事!这也是写模拟器及搜集资料时非常重要的一部份!
------------------------------------------------------------------------
3.4 SPU(声音处理单元)运作方式:
3.4.0 SPU(图形处理单元)的功能及地位:
与PPU一样,SPU用来专职处理声音.在比较古早的系统中,一般并不另外搭配专
用的处理器,而是由CPU直接控制.不过因为声音资料日益增多,于是另外搭配
专用的处理器,以减轻CPU的负担!随着CPU速度的加快,所搭配的SOUND CPU也
日益高级,从Z80,变成MOTOROLA 68000,逐渐变快!
3.4.1 SPU的组成:
包含SUUND PROCCESSOR,专用RAM,专用ROM,专用DSP,数位类比转换器等!简图
如下:
SPU
┌───┐ +---------------------------+
├───┤ | ┌───┐ |
│DATA ├─┬──────┬─┬┤RAM & │ |
├───┤┌┴─┐| ┌─┴┐││ROM │ |
│ ││CPU ├──┤SP ││├───┤ |
│ ││ │| │ ├┴┤SOUND │ |
│ │└──┘| └──┘┌┤CHIP │ |
│ │ | │├───┤ |
└───┘ | ││DAC │ |
ROM&RAM | └┤ ├──── SOUND OUT
| └───┘ |
+---------------------------+
大致上与PPU的组成是一样的!
CPU透过MEMORY MAP中的各个窗口,与SP(声音处理器,SOUND PROCCESSOR)沟通
并设定欲执行的功能!SP便到从ROM&RAM中搬移所要处理的资料到自己的RAM中
!接下来是功能解码,再从ROM中找出应该执行的指令,依序执行并指挥声音晶
片(SOUND CHIP)产生实际的声音资料,传递给DAC转换成声音讯号!
3.4.2 与PPU的不同处:
最大的不同处在于MONITOR还有VBLANK&HBLANK可以做很多事!SPU则必须不间
断的产生声音输出,同时声音晶片的模拟也是一大问题,这是模拟器的一大障
碍,所以模拟器一般都是发展到一定阶段了,机器的等级也到一定速度了,才逐
渐加入声音的支援!
3.4.3 声音处理器专用DSP的功能:
因为所选用的声音处理器不一定适于处理声音资料,尤其是FM与PCM有极大的
不同,PCM需要更强大的数值运算能力,因此有些系统会加入声音处理器专用
DSP,协助声音处理器处理PCM的运算!这也是搜集资料时的重要部份!
3.4.4 声音处理器的指令:
一般来说,CPU传给声音处理器的资料,将会是这个声音处理器的指令.所以必
须加入CPU CORE处理指令解码,例如是Z80的,就必须加入一个Z80的CPU CORE,
用来处理声音资料,同样有频率及定址空间的设计,整个SPU基本上就是一个隐
含的完整电脑系统!
------------------------------------------------------------------------
3.5 ROM & RAM AREA
3.5.0 SYSTEM ROM:
在某些TVGAME或ARCADE基版上会加入所谓SYSTEM ROM,这个SYSTEM ROM有几种
功能:
A.执行开机检查程式及O.S.!
B.储放重要或常用函式!
C.储放PPU,SPU常用函式!
D.储放中断向量及中断处理常式
这样的作法,明显的可以减轻GAME ROM的成本,不用每一个GAME ROM都需要挪
出空间放置这些程式,而使得成本降低!简单的说,SYSTEM ROM就等于是PC上的
作业系统!通常设置的目的是方便游戏开发人员能方便的使用一些特殊或常用
函式,基版设计厂商则必须尽量加入需要的功能函式!所以,如果你想写的主机
上有SYSTEM ROM的话,你必须想办法DUMP下来,因为不管是CPU,或者可能有PPU
,SPU都会存取到这里,执行这里的程式!
3.5.1 没有SYSTEM ROM的基版:
大部分为单一游戏或非系统基版的情况!必须在GAME ROM中拨出空间放置等同
于SYSTEM ROM功能的程式,因为是单一游戏,可以依个别情况撰写,空间的损失
并不大!通常会在基版开机时,就会从ROM中载入并执行开机检查程式!
3.5.2 GAME ROM
除去了SYSTEM ROM的部份,剩下来的就是GAME ROM的部份,按照功能可以分成:
A.PROGRAM AREA 程式区:
提供CPU指令的区域!
B.GRAGHIX DATA AREA 图形资料区 :
提供PPU图形资料的部份!
C.SOUND DATA AREA 声音资料区:
提供SPU声音资料的部份!
D.其他资料区
不同的基版设计,处理这些ROM的方式也不同!以家用主机大部分的设计来说,
所有的ROM DATA是按照其位址分开的,从外观上不易看出,DUMP时也都是直接
DUMP成一整个ROM IMAGE FILE(目前只有FC有分开DUMP的ROM IMAGE FILE出现
)!其原因应该是卡匣的体积,面积有限,不适于分开放置!
ps: 这也可能是DUMP工具的问题,家用主机的ROM DUMPER(或称为ROM COPIER)比
较常见的都并不是一个ROM IC一个ROM IC的DUMP!
相对于家用主机的情形,ARCADE则是能够从ROM IC放置的区域分别出这颗ROM
IC的内容及用途!一般来说,在DUMP这些基版的ROM IC时,都会按照其用途或
SCHEMATICS 上的编号命名,方便识别及载入至正确位址!
3.5.3 以光碟做媒介的ROM -- CD ROM:
CD ROM的处理方式与一般的卡匣或是基版上的ROM IC载入的方式并不相同!因
为必须从CD ROM中分段载入所需要的程式段,图形资料段,声音段!所以分区的
情况不明显,而是以当时游戏进行的状况处理!
3.5.4 GAME ROM的MAPPER 问题:
如果你是准备写家用主机的模拟器的话,所要面临的便是可能出现一个ROM
MAPPER 问题,ROM MAPPER问题是指MEMORY MAP中提供给ROM的区域比实际ROM
的容量还小,于是必需存在一个切换ROM BANK的暂存器(以MEMORY MAPPING I/O
方式读写)或是其他的机制,利用这些机制与MEMORY MAP中的ROM 区域而使得
能读取到更大的GAME ROM!这些机制就被称为MAPPER,模拟出MAPPER的机制就
是MAPPER问题!目前这个问题仍然困扰着FC模拟器的作者们,因为已知的MAPPER
格式就超过40种,不管是不支援某一种MAPPER或是MAPPER程式写的不好,这都
不能使你的模拟器完美!是你在搜集资料时必须注意到的!
3.5.5 如何开发游戏:
一般来说,主机公司会提供开发工具,提供游戏厂商开发游戏!游戏厂商利用开
发工具,撰写高阶的原始程式,绘制图形,编写乐谱及音效等,经过DEBUG后,把
全部的档案经过排列之后做成转烧成ROM IC,或是直接压制成CD!
3.5.6 ROM中的程式如何控制硬体:
应该有三种方式:
A.直接控制:
在开发时撰写低阶的硬体直接控制程式,理论上效能较快且可能创造出不
同的效果!游戏厂商需对硬体有相当认识,同时开发较不易!
B.呼叫SYSTEM ROM中的函式:
算是一种间接控制的方式.写高阶程式但是以呼叫SYSTEM ROM中的函式来
控制硬体!SYSTEM ROM中的函式因为容量因素,肯定不会大到哪去也不会
太多,游戏厂商还是大部分需要自己写!效能亦相当不错!
C.利用开发工具中内附的函式:
利用开发工具是最方便的方式,开发工具内附的函式到最后仍然会展成前
面两种方式控制硬体!不过开发工具的良窳会影响到游戏的开发,这点也
是很重要!
实际上通常都是这三种方式交叉使用,端看游戏厂商的能力!
------------------------------------------------------------------------
3.6 摇杆控制装置及钱币计数器等NMI的处理
3.6.0 摇杆通知CPU有按键按下的原理:
当有按键按下时,连接在基版的控制晶片会发出对CPU发出一个中断讯号,并且
把按键资讯写入到分配在MEMORY MAP中的位址!CPU接收到这个中断讯号之后,
中断现在的工作,先处理按键输入!处理完之后,在回到中断前的程式,并根据
接收到的按键讯息做反应!看起来会像这样:
┌───┐
│ │
┌──┐ ┌────┐ ├───┤
│摇杆├─┤控制晶片├─┤ ├┐
└──┘ └────┘ ├───┤│┌──┐
│ │└┤CPU ├─ 执行
│ │ └──┘
└───┘
记忆体中存放按键资讯的位址(MEMORY MAPPED IO)
3.6.1 MEMORY MAP中分配给摇杆控制装置的方式:
因为TVGAME,ARCADE一般都是使用数位式的摇杆,也就是只有[按下]及[没按下]
两种反应,分别以1BIT代替一个按键,看起来会像这样:
上 下 左 右 B1 B2 B3 B4
┌─┬─┬─┬─┬─┬─┬─┬─┐
│7 │6 │5 │4 │3 │2 │1 │0 │
└─┴─┴─┴─┴─┴─┴─┴─┘
按键多一点的用2 byte:
上 下 左 右 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│7 │6 │5 │4 │3 │2 │1 │0 │7 │6 │5 │4 │3 │2 │1 │0 │
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
更多的按键的,像麻将,当然就继续加下去!几P就加几组了!
3.6.3 非数位式摇杆的输入:
就流程上基本上是与数位式摇杆相同!问题在于如何输入资料于给定的位址中
,随着不同的摇杆会有不同的设计,这是搜集资料时一定找到的!但是找到之后
,更严重的问题是如何对应到PC的指向装置!要是不幸找不到对应的装置,你基
本上就直接放弃好了!
3.6.4 钱币计数器,START键等NMI的处理:
NMI是指"NON-MASKABLE INTERRUPT(NON-MASKED INTERRUPT)",也就是不可遮
罩的中断!这与一般中断有何不同呢?相对于NMI,其他的中断是属于可以被暂
时忽略(称为MASK掉),CPU可稍后再处理!而NMI是CPU无论如何都必须放下手边
的工作,必须优先处理这个中断!在TVGAME系统中,PPU的VBLANK就是属于一个
NMI,因为它必须萤幕更新等动作,此时PPU必须抢到周边的使用权,它会强迫
CPU暂停手边的工作!同样的,在ARCADE系统中,像投钱,1P select,1P start,
2P select,2P start,这种动作当然是一定要优先处理!不过.有些产生NMI的
装置,如PPU,还是可以利用一些暂存器的设定,使它暂时不要产生NMI,这些暂
存器的位址,设定的方式,也是在搜集资料时要找到的!
------------------------------------------------------------------------
3.7 RESET处理:
3.7.0 加入RESET的原因:
不管是TVGAME还是ARCADE,游戏通常都是不会停止的!问题是,还是有某些情况
必须要重新开机一次,例如:进到硬体测试画面,设定DIP SWITCH,使用某些密
技,打不赢人家耍贱,就是想重新开机等等!更重要的是,不断开关电源会可能
导致硬体损坏!所以必须要有一种机制可以暂时切断电源,使系统重新开机,这
种机制便是RESET!
3.7.1 RESET的流程:
RESET的第一步当然是暂时切断电源!重新初始化CPU,周边等!载入SYSTEM ROM
进行开机测试,检查是否有需要处理特殊程序,如:进到硬体测试画面,设定DIP
SWITCH!如果没有,再载入GAME ROM,开始游戏!
------------------------------------------------------------------------
3.8 DIP SWITCH:
3.8.0 加入DIP SWITCH的原因:
因为ARCADE系统是一个赚钱的工具,一成不变的游戏在被人摸熟时,就没有人
玩了,同时还有不少游戏的参数要设定,所以需要一种方便的储存游戏参数的
工具,于是在基版上加上DIP SWITCH,只要开关拨一拨,就能设定参数!不需要
外加电源!但是新一代的基版有些就不是使用DIP SWICH,而是利用EEPROM储存
,这样就不须要用手拨DIP SWITCH了!
3.8.1 DIP SWITCH的作用方式:
说穿了,也只不过是一些逻辑电路!但是利用程式检查电路短路与否,赋予实际
的意义,例如:投多少COIN才算一次CREDIT;设定出红血看起来暴力一点;或是
无敌之类的!不过少了设定DIP SWITCH的功能,并不会有什么问题,只是没那么
完美罢了!但是DIP SWITCH是用"手"设定的,所以如果要做DIP SWITCH就要做
设定函式代替用手拨开关!当然你还是需要找到该游戏DIP SWITCH图,才能知
道各开关的定义!
------------------------------------------------------------------------
3.9 BACKUP DEVICE
3.9.0 需要BACKUP DEVICE的原因:
不是每一种游戏都能一次玩完的,例如RPG,SLG等,于是需要一种能保存资料的
装置!古早之前,是利用特殊编码的CODE来保存资料!不过这不是办法,越复杂
的游戏或是需要保存的资料越多,CODE会变得越来越长!于是出现划时代的装
置---利用电池提供SRAM的电源,把资料储存在SRAM中!一般称为"电池记忆",
但是用电池还是有问题--电池是有寿命的!新一代的便是使用FLASH ROM,不须
外加电源,可重复写入!
3.9.1 存取BACKUP DEVICE的方式:
和其他装置一样,在MEMORY MAP有保留给BACKUP DEVICE的空间,只要把资料搬
过去就行了!在此之前,当然是需要先知道MEMORY MAP的空间在哪里!
------------------------------------------------------------------------
3.A DMA CONTROLLER
3.A.0 什么是DMA(DIRECT MEMORY ACCESS) CONTROLLER?
详细的原理及机制请找计算机组织之类的书!总之就是不想让资料传输通道闲
着及减轻CPU的负担,使CPU不需要自己处理资料的搬移!于是设计了一个专门
处理资料搬移的处理器,便称为DMA CONTROLLER,处理的范围是RAM与周边I/O!
因为它也是一个处理器,所以CPU与DMA CONTROLLER的沟通是有一定程序的!如
果想写的系统也具有DMA控制器的话,就必须搜集有关DMA控制器的资料!
3.A.1 DMA的运作方式(从书上抄来的):
COMPUTER ORGANIZATION & DESIGN --- DAVID A. PETERSON/JOHN L. HENNESSY
DMA传送中有三步骤:
A.由装置本身提供DMA,而操作命令是根据记忆体位址,位元数目并在装置上
执行资料的传送.
B.DMA在装置上开始操作命令并重才汇流排.当资料可用时(从装置或记忆体
),它传送此资料.而DMA装置对读取或写入提供记忆体位址.若在汇流排上
需求资料超过一次以上,DMA 单元将产生下一个记忆体位址并启动下一次
传送.DMA使用这种机制,在不用干扰处理机情况下,它能传送数千位元组
资料.在很多DMA控制器包含一些缓冲区允许它们在传送资料或等待成为
汇流排主控器时来处理延滞时间的可塑性.
C.一旦DMA传送完成时,控制器将中断处理器,然后处理器查询DMA装置或记
忆体,是否整个操作命令成功地完成.
------------------------------------------------------------------------
3.B 光碟机装置
3.B.0 使用CD-ROM DRIVER的原因:
随着游戏的声光效果越来越好,GAME ROM的容量也随之不断上升!原来所使用
的ROM IC在应用上已经有所困难!这个困难包括两方面,卡匣的尺寸会随着ROM
IC的增加而变大,另一方面,容量越大的游戏,不是ROM IC用的更多,就是必须
改用大容量的ROM IC.而不管哪一种,显而易见地都会带来成本上升的影响,造
成卡匣价钱上升!就目前而言,解决的方式有两种:一是对资料进行压缩,仍然
使用ROM IC制成卡匣的型式,优点是保有卡匣不须等待,速度较快的优势,缺点
是就算是压缩过后,还是不一定能解决容量的问题,语音及动画都是属于不易
再压缩的资料,只好忍痛删除,例如N64!另一种解决的方式是改用CD-ROM作储
存媒体,优点是再没有容量上的限制,只要增加CD-ROM片数即可,同时成本低廉
,价钱便宜!缺点是CD-ROM的存取时间远大于卡匣!例如:一堆次世代机!
3.B.1 CD-ROM的存取方式:
CD-ROM的容量有650Mbyte,大部份使用CD-ROM DRIVER的系统,其主记忆体通常
并不足以容?#123;所有资料存放于主记忆体中,于是必须以分段读取的方式存取!
┌─────────┐
│CPU 读取某一段资料│
└────┬────┘
│
┌────┴─────┐
│是否存在于主记忆体中│
YES └────┬─────┘ NO
┌────────┴─────────┐
│ │
┌───┴────┐ ┌────┴─────┐
│ 从主记忆体读取 │ │ 是否存在于缓冲区中 │
└───┬────┘ YES └────┬─────┘ NO
│ ┌───────┴───────┐
│ ┌───┴─────┐ ┌───────┴──────┐
│ │ 从缓冲区搬移资料 │ │ 对CD-ROM控制器提出读取要求│
│ │ 到主记忆体 │ └──────┬───────┘
│ └───┬─────┘ │
│ │ ┌──────┴────┐
│ │ │现在的碟片存在此资料 │
│ │ YES └────┬──────┘ NO
│ │ ┌────────┴───────┐
│ │┌──┴──┐ ┌───┴┐
│ ││ 从目前的 │ │换片读取│
│ ││ 碟片读取 │ └─┬──┘
│ │└──┬──┘ │
│ │ │ │
│ │ └──────┬───────┘
│ │ ┌────┴───────┐
│ │ │ 资料从碟片读入至缓冲区 │
│ │ └────┬───────┘
│ │ ┌─────┴────────┐
│ │ │资料从缓冲区COPY至主记忆体 │
│ │ └─────┬────────┘
│ │ ┌─────┴───────┐
│ │ │CD-ROM控制器对CPU发出中断,│
│ └────┤通知CPU已完成读取动作! │
│ └─────┬───────┘
│ │
└─────────┬───────────┘
┌─────┴────┐
│CPU完成资料读取动作 │
└──────────┘
这一个流程图实际上还忽略了CD-ROM DRIVER硬体的动作,这才是真正最耗费
时间的地方!
另外这其实不太像TV GAME主机会干的事,这样的检查算起来还是太多,应该是
跳过第一个判断,因为需常驻的资料区及指令区不动,剩下的MAIN MEMORY全部
使用画面处理及声音上,旧资料全部放弃,从CD ROM中读取新资料,自然就不用
检查资料在不在!优点是分配处理画面及声音的MEMORY够大,可以作出超炫CGA
及全程语音,缺点是CD ROM DRIVER的SEEK TIME过慢及BUFFER过小时,等待时
间会很长,又需要利用画面处理的技巧解决及妥善安排档案位置解决!
无论如何你需要知道系统对CD-ROM存取的详细流程,所发出的中断要求,所分
配的MEMORY MAP位置,容量等!
------------------------------------------------------------------------
3.C 其他周边
对于ARCADE系统中,当然还有其他的周边,我建议可以到亚站及巴站的ARCADE
版中,找寻相关的资料!
对于TV GAME系统,所剩下的就是接到TV上了!
[ 第四步 模拟器的运作方式 ]
4.0 模拟器与真实的硬体还是有差距的
姑且不论模拟的像不像,好不好,从执行时的情况看来,真实的硬体是允许平行
处理的,而模拟器却是以循序的方式,轮流使用PC CPU的资源!有很多硬体的机
制是模拟器做不来的,全盘以硬体的角度看模拟器,会发现有很多东东是无法
实作的,单从模拟器的角度看硬体,也会发现文件实在漏掉太多东西!以下的大
部分内容是以解读SNES9X 1.10,MAME 35b5的原始档内容所撰写的,就SFC的硬
体而言,算是满符合上面所分类的项目,除了缺少CD-ROM DRIVER的部份之外,
此外有很多都是我个人的想法,不一定是正确的,这点一定要知道!
------------------------------------------------------------------------
4.1 CPU的处理
当你选定了CPU之后,自然便是需要模拟那个CPU的运行!模拟器的CPU与真实的
CPU有很大的不同,可以分为:
A.CPU CORE:负责解译指令!
B.EXEC_CPU:负责流程控制!
CPU CORE与EXEC_CPU组成了模拟器的核心,CPU与外界的接触及排程由EXEC_CPU
控制,在NMI,SPU,其他装置何时执行,在其余时间再把ROM中的指令交由CPU CORE
解译及执行!执行的流程是由EXEC_CPU检查需不需要执行NMI,SPU,及其他装置
,若需要执行,则执行NMI等相关程式,若不需要执行,则从ROM中抓取指令交由
CPU CORE解译及执行,CPU CORE处理完再交回EXEC_CPU检查需不需要执行NMI,
SPU,及其他装置,直到程式结束为止!
以流程图表示:
┌───┐
│ 开始 │
└─┬─┘
┌──────────→│
│ ↓
│ ┌───────┐ EXEC_CPU
│ │ 取下一个指令 │
│ └───┬───┘ ↓
│ │-----------------
│ ↓ ↑
│ ┌───────┐
│ │ 执行指令 │ CPU CORE
│ └───┬───┘ ↓
│ │-----------------
│ ↓ ↑
│ ┌──┐ ┌────────┐
│ │停止│←┤SHOTDOWN CPU │ EXEC_CPU
│ └──┘ │检查中断 │
│ │行程中断 │
│ │执行或遮掉中断 │<---- 此时模拟器CPU等于
│ └────┬───┘ 处于暂停状况
│ │
└───────────┘
此时模拟器CPU等于又开始执行下一个指令
4.1.0 CPU CORE
CPU CORE的名称应该是指这个程式承继了真正CPU的核心,实际上也是,整个CPU
CORE只保留了暂存器,定址模式,OPCODE的解译及执行(含ALU,CU,IU,OU),PC(
PROGRAM COUNTER,程式计数器)改为整体变数(或EXEC_CPU的区域变数)等,去
除掉所有的中间暂存器(IR,MBR,MAR)!但是因为缺少了时序周期,必须增加另
外一个变数CLOCK_COUNT,当成时序周期来用,并对所有的OP-CODE加上一个会
用掉多少CLOCK的数值,当执行某一个OP-CODE 之后,CLOCK_COUNT必须减掉这
个数值,表示经过了多少个CLOCK!
有许多CPU CORE的作者,同样的也会有不少不同种类的CPU CORE!不同的CPU
CORE效果也大不相同!其中的差别在于:
A.所使用的语言不同:
以组合语言及C语言两种为主,一般以组合语言所写的速度较快!原因是可
以避免掉编译时所产生多余的码,不过实际上还必须评估每个OP-CODE花
多少码模拟,执行将花费多少时间等!
B.对OP-CODE解译的方式不同:
怎么做到有效率的模拟及正确的模拟OP-CODE,一直是CPU CORE作者的目
标,问题是每个人对于OP-CODE的解释不同,实作出来的CPU CORE便会发生
解译不同的情形!这种解译不同的情况,严重时,会导致模拟的效果不正确!
4.1.1 套用现成的CPU CORE :
有现成的CPU CORE 时,当然就是想办法直接套用!要注意套用的程序,例如,必
须先初始化CPU CORE,设定一个定址空间交给CPU CORE等!所以在套用之前,一
定需要先看过说明档,以求了解套用的程序!
4.1.2 自己做一个CPU CORE:
只好自己做一个!做一个CPU CORE模拟器,说难不难,说简单也是骗人!当然一
个简单的方式便是修改别人的CPU CORE的OP-CODE部份,修改成为你心目中认
为的OP-CODE模拟方式!我没有实际做一个CPU CORE模拟器的经验,只能有观
察别人的模拟器中提供一些经验!
需要提供几个重要的函式,这是CPU CORE的外观:
A.RESET_CPU(INITIAL_CPU):
把CPU CORE的状态恢复至初始时的状态!各暂存器,旗标,程式计数器!
B.CPU_SHUTDOWN:
释放CPU CORE所占用的记忆体!
C.OP-CODE DECODER&EXECUTOR:
解译并执行OPCODE的程式!写法很多,CASE-SWITCH,或是函式阵列等!不管
是CASE-SWITCH或是函式阵列都是利用转译前OP-CODE的十六进位数值当
成判断的依据!
就结构上来说,需要实作出这是CPU CORE的内在:
A.CPU的暂存器,旗标等!你可以直接定义一个CPU的结构,这样应用上较为便
利!
B.CPU的定址模式!直接定址指令为何,间接定址指令如何处理等!
C.CPU所用的每个OP-CODE,实作的方式满多的,需要ALU的OP-CODE直接用四
则运算代替等!你必须要先知道这个CPU提供多少种OP-CODE,每个OP-CODE
的运作方式,OP-CODE如何解码等,再一一实作出每个OP-CODE来!
我目前的程度,只能提供意见到这里!
4.1.3 MULTI-PROCCESSOR的场合:
面对多处理机的系统时,不可避免的问题就是:
A.必须实作出好几个CPU!
B.必须实作CPU的沟通方式!
对于问题A而言,可以以定义出CPU结构再宣告多个CPU结构当成有多个CPU,而
CPU CORE共用同一份!对于问题B而言,如果是MASTER/SLAVE系统,就是在
MASTER CPU的EXEC_CPU中多实作出处理SLAVE CPU中断及其他沟通的方式等!
4.1.4 CPU与其他周边沟通方式的处理
简单的说,就是处理中断的方式!真实的硬体是可以平行运作的,但是模拟器可
不行,至少在没办法写成几乎可平行运作又可相互沟通的执行绪前不行!由前
面的流程图可以发现,必须在EXEC_CPU中排入中断检查,中断执行,和一切周边
状态检查及更新的程式片段!整理一下,包括:
A.SPU状态的检查:
SPU状态的检查在整个模拟器占了很重要的地位,因为声音不能有任何中
断现象,所以几乎在每个函式都必须执行一次,在较长的函式中甚至必须
执行许多次,以确保声音不会中断!
B.摇杆状态检查:
检查摇杆按键是否有按下的讯息传来!
C.NMI中断检查:
检查是否有NMI中断发生,依其优先顺序执行!
D.一般中断检查:
检查是否有中断发生,依其优先顺序执行!
E.PPU定期资料更新:
简单的说就是画面的更新!前面CPU CORE段落中说到必须将每个OP-CODE
加上一个用掉多少CLOCK TIME的常数,在把PPU定期资料更新周期定义成
多少个CLOCK COUNT,每执行一个OP-CODE就扣掉一些,等到变成负数或等
于零时,就表示定期资料更新周期到了,就去执行资料更新的函式!这就
是没有时序产生器以产生时序的变通方法!
F.SPU定期资料更新:
若SPU中含有TIMER,则必须于一定时间时更新状态!这可保持整个模拟器
以一定的时序同步执行,因为有些装置是需要同步执行的!这个TIMER的
计算方式是以相对于多少CPU CLOCK TIME或是以相对于多少CLOCK COUNT
来计算!
4.1.5 DSP的处理
实际上有两种类型的DSP,这两种在处理有很大的分别:
A.模拟这个DSP的外在行为:
模拟时需要做一个DSP的结构与CPU沟通,但是实际上的内部执行只是呼叫
函式而已!例如给DSP算一个COS值等!这是模拟这个DSP的外在行为就可以
了!
B.模拟这个DSP的内在行为:
最明显的例子就是SFC的SuperFX晶片,这其实是一个RISC的处理器,必须
模拟出这个处理器的内在行为,OP-CODE等,就像模拟一个CPU一样!
------------------------------------------------------------------------
4.2 MEMORY MAP的处理
简单的说,就是配置所需的记忆体,包含ROM,RAM,SRAM,VRAM(PPU用)等!并载入
至对应的区域内!同时在模拟器结束时必须释放出所配置的记忆体!需要实作
出:
A.INIT MEMORY MAP:
也就是初始化MEMORY MAP,对ROM,RAM,SRAM,VRAM(PPU用)都配置足够大的
记忆体!不过倒是不需要只配置一大块记忆体当成整个MEMORY MAP,分成
RAM区,SRAM区,ROM区也可以,但是存取时必须视为一整块MEMORY MAP!另
外还有一些需要配置的记忆体区块,也能在此一同处理!
B.FREE MEMORY MAP:
在模拟器结束时,必须释放出原来配置的记忆体,在这个函式中处理!
C.LOAD ROM IMAGE FILE:
档案处理的部份不在这边做,这里直接用档案指标参数操作!把档案内容
搬移到MEMORY MAP中分配给ROM的区域!一般而言,除了CD-ROM之外,都是
配置出足够的大小,很明显的,如果ROM IMAGE有50MBYTE,就需要配置出
50MBYTE!这里需要注意一下,有些系统的ROM区域是分段的,LOW ROM&HIGH
ROM,也需特别处理!
D.LOAD/SAVE SRAM FILE:
与LOAD ROM IMAGE FILE处理的方式一样!比较不一样的是,SRAM FILE要
随时准备存取,ROM IMAGE FILE一般只有在更换游戏时才会更动!
E.LOAD SYSTEM ROM FILE:
与LOAD ROM IMAGE FILE处理的方式一样!
F.FIX ROM SPEED:
有时候,会需要模拟ROM存取的速度!
G.特殊晶片的ROM IMAGE处理:
有些晶片或是PPU,SPU会有用到专用的ROM,原则上仍然等同LOAD ROM
IMAGE FILE的方式处理!
这里提供的还是原则性的写法,详细的内容,还是得多看看别人的处理方法!
4.3 PPU的处理
4.3.0 PPU的处理
在大部分的情况而言,通常都不会知道PPU是什么晶片,所用的OP-CODE等,也找
不到相关的资料,通常找到的是CPU透过MEMORY MAP的窗口与PPU沟通的资料,
所以模拟的方式一般都是模拟外在的行为,而不是模拟内在的操作情形!无论
如何,需要提供:
A.RESET PPU(INIT PPU):
重新把每个MEMORY MAP所对应的功能的参数,恢复成初始的状态!
B.CPU设定PPU的函式:
也就是处理那些MEMORY MAP的功能的函式!与CPU的OP-CODE不太一样,这
里较常用CASE-SWITCH的结构!原因是速度较快吧!以MEMORY MAP所分配的
"位址"当成SWITCH的判断依据!
C.CPU读取PPU处理后状态的函式:
也就是处理完那些MEMORY MAP的功能之后,预备由CPU读取的函式!也是使
用CASE-SWITCH的结构!这里不一样的地方是,并不是每个功能都有传回资
料,某些CASE的处理就可直接跳过!也是以MEMORY MAP所分配的"位址"当
成SWITCH的判断依据!
不过这都只是外观而已,真正的还是模拟每个功能的程式,一般找得到的资料
会像这个样子,以SNES9X为例:
SNES Documentation v2.30: Written by Yoshi
----------------------------------------------------------------------------
|rwd2?|Address|Title & Explanation |
||||||-----------------------------------------------------------------------|
|||||| |
||||||__ ?: Don't know what the statistics on this register are |
|||||____ 2: 2 byte (1 word) length register |
||||_____ d: Double-byte write required when writing to this register |
|||______ w: Writable register |
||_______ r: Readable register |
| |
|Words in brackets ( [] ) are the official "names" of the registers |
|Words in braces ( {} ) are different from the "real" SNES manual |
|Bits define 1 as "ON/ENABLE" and 0 as "OFF/DISABLE," unless otherwise stated|
|Registers without any bits/defined-data can be assumed to be 8 bits in size |
|and should only be read once. |
----------------------------------------------------------------------------
|rwd2?|Address|Title & Explanation |
|----------------------------------------------------------------------------|
| w |$2100 |Screen display register [INIDISP] |
| | |x000bbbb x: 0 = Screen on. |
| | | 1 = Screen off. |
| | | bbbb: Brightness ($0-$F). |
| | | |
| | | |
----------------------------------------------------------------------------
按照说明写成对应的程式:
========================================================================
case 0x2100:
// Brightness and screen blank bit
if (Byte != Memory.FillRAM [0x2100])
{
FLUSH_REDRAW ();
if (PPU.Brightness != (Byte & 0xF))
{
IPPU.ColorsChanged = TRUE;
PPU.Brightness = Byte & 0xF;
S9xFixColourBrightness ();
if (PPU.Brightness > IPPU.MaxBrightness)
IPPU.MaxBrightness = PPU.Brightness;
}
if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80))
{
IPPU.ColorsChanged = TRUE;
PPU.ForcedBlanking = (Byte >> 7) & 1;
}
}
break;
========================================================================
关于如何写才算完美,对不起,我没有办法说明!而实际上,这就是一个模拟器
好坏的差别!
需要补充的是,通常在CPU设定PPU的函式中会把像SPU,DMA等同样使用CASE-
SWITCH结构的函式放在同一个CASE-SWITCH结构中!只是执行的函式本体另外
写而已!
4.3.1 实际绘图的动作:
上面拉拉杂杂一堆,就整个PPU而言,仍然只是外观而已!只是设定PPU去做某一
件事,设定它的参数,你还是得实作出真正绘图的动作!这里还是受限于我的知
识不足,等到以后再补充!另外,需要做一个初始动作的函式,这是处理PPU内部
的初始化!
4.3.2 SCREEN REFRESH
SCREEN REFRESH有两种:
A.模拟硬体处理SCREEN REFRESH的动作:
这里还是受限于我的知识不足,等到以后再补充!
B.实际显示出画面于MONITOR上:
这里还是受限于我的知识不足,等到以后再补充!
------------------------------------------------------------------------
4.4 SPU运作方式:
4.4.0 SPU(图形处理单元)的功能及地位:
4.4.1 SPU的组成:
4.4.2 与PPU的不同处:
4.4.3 声音处理器专用DSP的功能:
4.4.4 声音处理器的指令:
------------------------------------------------------------------------
4.5 摇杆控制装置及钱币计数器等NMI的处理
4.5.0 MEMORY MAP中处理摇杆控制装置的方式:
除了一些特殊控制器之外,摇杆上的每个按键或是方向键都是用1BIT表示其状
况--按下或是没按下!直接由MEMORY MAP所分配的位址下手,但是因为PC上可
拿来控制的装置太多了,需要一个中间程式转换,大致如下:
┌───┐┌───┐
│键盘 ├┤DRIVER├┐ MEMORY MAP所分配的位址
├───┤├───┤│ ┌───┐
│滑鼠 ├┤DRIVER├┤ │ │
├───┤├───┤│┌────┐├───┤ ┌────┐
│摇杆1 ├┤DRIVER├┼┤转换程式├┤ PAD ├─┤EXEC_CPU│
├───┤├───┤│└────┘├───┤ └────┘
│摇杆2 ├┤DRIVER├┤ │ │
├───┤├───┤│ │ │
│摇杆3 ├┤DRIVER├┘ └───┘
└───┘└───┘
摇杆?表示
另一种摇杆,不是另一只
这样画是稍微不正确,不过讲解很方便!要加入一种新的装置,就需要有专用的
DRIVER才能支援到!所谓专用的DRIVER是指如何读取讯号,怎样解读所得到的
讯号是什么意义,负责这种工作的程式,一些特殊的指向装置都会提供专用的
开发工具,这些开发工具便会提供如何解读所得到的讯号,其实这就是我所指
的DRIVER!DRIVER是对应WINDOWS的说法!摇杆的动作不正常,乱跳啦,不支援某
种摇杆啦,就是DRIVER层级的问题!重新对应所按的按键,或是选择不同的装置
输入讯号,就是转换程式的问题!控制装置所找到的DRIVER不同的话,支援的情
况就有很大的差别!就WINDOWS模拟器而言,比较新的通常都使用DIRECT X的
DIRECT INPUT支援不同的指向装置,这样非常方便,只要符合DIRECT INPUT的
函式呼叫,就通用所有指向装置!但是DOS模拟器并没有这么简单,必须一种一
种的支援!
另外我把指向装置切换及按键重定义视作转换程式!转换程式的目的在于适当
的把所选择的指向装置上所按的按键转换成所模拟TV GAME主机的按键资讯字
组!很明显的,具有三种功能:
1.选择所支援的指向装置!
2.可自由定义所选择的指向装置上的按键对应所模拟主机上的按键!
3.转换所选择的指向装置上的按键定义成为所模拟主机使用的资讯!
不过其实还有第四种功能:
4.热键(HOT KEY)处理界面!
转换程式一般都是利用CASE-SWITCH结构设计,不论是处理何种指向装置的DRIVER
提供的讯息!而K/B的所使用的CASE-SWITCH结构,还可以加入热键处理,例如呼
叫GUI,RESET,FRAMESKIP,抓图,当然还有EXIT--退出模拟器,处理方式就是增
加CASE,当KB有按键按下时,属于模拟器摇杆的部份就组合成正确的字组填入
MEMORY MAP的位址,其他的则检查是否属于热键,是则执行对应的热键处理函
式,再不属于热键的就直接忽略掉!
不管是什么指向装置,到了转换程式最后都会变成所模拟主机的按键资讯字组
!然后设定一个中断FLAG,等到模拟器控制权又回到EXEC_CPU时,将会检查这个
中断FLAG,再读取这个按键资讯字组,然后CPU CORE会根据这个字组,执行ROM
中的程式!
4.5.1 特殊指向装置的处理:
下次再写!
4.5.2 钱币计数器,START键等NMI的处理:
不管是何种NMI,都是设定一个中断FLAG,等到模拟器控制权又回到EXEC_CPU时
,将会检查这个中断FLAG,再读取这个按键资讯字组,然后CPU CORE会根据这个
字组,执行中断服务常式或ROM中的程式!
------------------------------------------------------------------------
4.6 RESET处理
算起来这个最简单,把所有相关的初始函式,全部关在一起呼叫一次,就是RESET
了!如果要处理一些特殊动作,也是在这里处理,当所有初始函式执行完成之后
,再执行想要做初期奇怪动作的函式!这个功能的呼叫方式通常是设置在按键
读入的处理函式中,在CASE-SWITCH结构中,多一个CASE处理RESET!
------------------------------------------------------------------------
4.7 DIP SWITCH作用处理方式:
这个也是满简单的,设计一个以位元操作的方式定义出DIP SWITCH的结构,最
好是附以显而易见的定义,最后是设计一个专门处理设定DIP SWITCH功能的函
式,有专用的画面及控制方式等!比较懒的方式是,让使用者自己计算出要设定
DIP SWITCH功能的十六进位数值,模拟器只要读入这个数值即可!这个功能的
呼叫方式通常是设置在按键读入的处理函式中,在CASE-SWITCH结构中,多一个
CASE处理DIP SWITCH!
------------------------------------------------------------------------
4.8 DMA CONTROLLER运作处理方式
模拟器是不可能会有DMA这种机制的,当DMA功能启动时,实际执行时是从EXEC_CPU
函式中直接转移到DMA控制函式,进行字组的搬移,但是要定时或完成一个动作
时,需要模拟DMA CONTROLLER对CPU发出中断的动作,这个动作就是整个DMA函
式的核心,而资料搬移动作反而是最不重要的,因为这个动作就是资料搬移的
动作:
TARGET_MEM = SOURCE_MEM;
还有一个动作要处理,就是CLOCK TIME的动作,不论DMA多快,都不可能在不经
过任何CLOCK TIME就能完成,我们需要模拟CLOCK TIME经过的动作!
你会发现EXEC_CPU转移到DMA控制函式时,整个模拟器CPU是处于暂停的状态,
这也是符合DMA运作的机制!
前面都是DMA CORTROLLER的内部机制:
A.模拟DMA CONTROLLER对CPU发出中断的动作!
B.资料搬移动作!
C.模拟CLOCK TIME经过的动作
还必须提供CPU使用DMA的机制,CPU对DMA CONTROLLER的控制方式还是以MEMORY
MAP中分配给DMA CONTROLLER的窗口设定DMA CONTROLLER的参数,在DMA
CONTROLLER动作时便按照这些参数运作,需要实作出以下的函式:
A.RESET_DMA:
恢复DMA CONTROLLER成初始状态!
B.DMA 传输模式:
必须提供所使用DMA的所有传输模式!CYCLE STEALING就是搬移一个字组
就把控制权交回EXEC_CPU,BURST MODE除了资料搬移外,还需要处理经过
多少CLOCK TIME!
------------------------------------------------------------------------
4.9 光碟机装置存取方式:
有空再写!

------------------------------------------------------------------------
4.A 档案处理:
4.A.0 档案载入
有空再写!

4.A.1 LOAD HISCORE FILE
有空再写!

4.C.2 LOAD/SAVE 随时记忆档
有空再写!

------------------------------------------------------------------------
4.B 特殊功能:
4.B.0 抓图
有空再写!

4.A.1 抓音乐档
有空再写!

4.B.2 GUI
有空再写!

4.B.3 CHEAT CODE
有空再写!

4.B.4 CHEAT TOOL
有空再写!

4.B.5 DISASM
有空再写!

------------------------------------------------------------------------
4.C 可携性版本,WINDOWS版本,更先进的模拟器架构
有空再写!

4.C.0 可携性的研究
有空再写!

4.C.1 WINDOWS版本
有空再写!

4.C.2 更先进的模拟器架构
有空再写!
