如何编写一个硬件夜神模拟器 脚本编写

模拟硬件,最全面的模拟硬件文章 - 电子工程世界网
在电子工程世界为您找到如下关于“模拟硬件”的新闻
模拟硬件资料下载
,已经完全进入高科技领域。非广播电视领域(电视监控技术)分为3个阶段:模拟阶段、数字与模拟阶相结合及全数字阶段。&  关键词:电视监控系统&多媒体技术&网络传输技术&发展&  1、电视监控技术来源于非广播电视技术。随着电视的产生,电视分为两种技术,一种是广播电视技术,它是录好的,经过编辑的(如电视台播放的电视剧),但并不反映实况,可以向大众广播...
谈谈EDA的硬件描述语言(654)9.2 基于VHDL语言的FPGA设计(657)9.3 VHDL的设计特点与应用研究(662)9.4 单片机应用系统的CPLD应用设计(668)9.5 用CPLD实现单片机与ISA总线接口的并行通信(674)9.6 FPGA实现PCI总线接口技术(679)9.7 用FPGS实现DES算法的密钥简化算法(685)9.8 可编程模拟器件原理与开发(690)9.9 数字...
............................................................................................................186
9.1.1 用户自定义指令的概念.....................................................................................186
9.1.2 硬件接口...
本书全面、系统地介绍了MCS-51系列单片机应用系统的各种实用接口技术及其配置。   
内容包括:MCS-51系列单片机组成原理:应用系统扩展、开发与调试;键盘输入接口的设计及调试;打印机和显示器接口及设计实例;模拟输入通道接口技术;A/D、D/A、接口技术及在控制系统中的应用设计;V/F转换器接口技术、串行通讯接口技术以及其它与应用系统设计有关的实用技术等。   本书是为满足广大科技工作者...
硬件,能够像生物一样根据环境的变化改变自身的结构以获得最优的适应性能。它是一种具有自适应与自修复特性的仿生态硬件电路, 它是新兴的仿生电子学的主要研究内容之一.也是一种新颖的硬件设计思想与方法。硬件进化技术的用途广泛,特别是对于电子设备需要长期工作、使用环境恶劣、技术人员无法及时提供维修的情况尤其有用,尤其在航空、航天领域具有重要实用价值。在电路设计中,模拟电路和数字电路存在各自不同的特点,对于进化...
(高清晰度数字电视)试播后,又一次掀起了机顶盒的高潮,这次机顶盒的主要作用是用普通模拟电视机收看数字电视或数字高清晰度电视,当然也具备网络和有条件接收功能,这种机顶盒被称为数字电视机顶盒。根据传输媒体的不同,数字电视机顶盒又分为数字卫星机顶盒(DVB-S)、地面数字电视机顶盒(DVB-T)和有线数字电视机顶盒(DVB-C)三种,三种机顶盒的硬件结构主要区别在解调部分。目前应用较为广泛的是数字卫星机顶盒及...
/O电路和装置PLC (Programmable Logic Controller):用于完成与逻辑运算有关顺序动作的I/O控制,它由硬件和软件组成;机床I/O电路和装置:实现I/O控制的执行部件(由继电器、电磁阀、行程开关、接触器等组成的逻辑电路;功能:接受CNC的M、S、T指令,对其进行译码并转换成对应的控制信号,控制辅助装置完成机床相应的开关动作接受操作面板和机床侧的I/O信号,送给CNC装置...
模拟电梯的设计与实现一、实验目的 1.了解电梯调度算法。 2.利用微机实验系统来模拟电梯。 3.进一步掌握微机接口的设计方法。二、实验内容与要求1.设计基本要求 用键盘、按钮、发光二极管和 LED显示单元来模拟电梯工作过程。楼层设为 5 层,用键盘键入希望停的楼层, 5 个 发光二极管显示希望停的楼层,LED指示电梯当前所在楼层,按钮用来启、停电梯。电梯正常运行时以每 2 秒1层的速度上升或下降...
嵌入式系统设计师考试大纲(2009版)一、考试说明1、考试要求:(1)掌握科学基础知识;(2)掌握嵌入式系统的硬件、软件知识;(3)掌握嵌入式系统分析的方法;(4)掌握嵌入式系统设计与开发的方法及步骤;(5)掌握嵌入式系统实施的方法(6)掌握嵌入式系统运行维护知识;(7)了解信息化基础知识、信息技术引用的基础知识;(8)了解信息技术标准、安全,以及有关法律的基本知识;(9)了解嵌入式技术发展趋势...
LabVIEW, LabWindows/CVI, 和Measurement Studio)和高阶测试与数据管理工具三部分共同组成。通过使用隶属于该架构的简单易用的开发环境,如LabVIEW,可以在很短的时间内完成测量与控制系统的模拟,原型建立,设计,配置和修改等任务。2&系统的硬件组成&& PXI简介[1]PXI是一种专为工业数据采集与自动化应用度身定制的模块化仪器平台...
模拟硬件相关帖子
板卡可以实现2通道万兆光纤的高速采集、实时记录和宽带回放。该板卡为标准半高半长尺寸,适合于目前主流半高机箱的服务器或超微工作站。1.2 功能框图图1-1 板卡功能框图1.3 硬件指标q 标准PCI Express半高半长卡,适合于半高机箱。q 符合PCI Express Gen2.0规范,可选x1、x4或x8模式,理论带宽高达40Gbps。q 2路万兆光纤网络接口,最大支持10Gbps/lane线...
  高清网络摄像机,指的是基于数字化、网络化传输方式的监控系统摄像机,监看及录像分辨率至少要达到以上,低于此的均是假高清或不属于高清。传统模拟监控系统的监看和录像分辨率由于技术上的限制,目前最高只能达到D1分辩率的效果,因此,无论模拟摄像机是多少线,均不属于高清的范畴。
  在进入高清时代之后,以上这些技术问题都很快得到了解决。目前已经形成了以日系镜头、台湾镜头和国产镜头为代表...
。它也是为运行开源软件而构建的一个系统,以及为展示德州仪器的芯片。这个主板由一个小组开发并以对高校展示开源硬件/软件能力为导向而设计。而BeagleBone是BeagleBoard的精简版,价格也有所“精简”。
要注意BeagleBone Black的官方定价是45美元(也是BeagleBoard系列里最便宜的),但这比Raspberry Pi高配版本一如既往的35美元定价还是高了近30%。近期...
传感器。在小型个人运输装置中,这些可能是低成本磁性霍尔传感器,而在较大的公路应用中,它们可能使用解算器。分解器是一种模拟绝对位置传感器,因其整体坚固性和紧凑外形而闻名。旋转变压器传感器由正弦载波输入激励,且转子的绝对位置被编码到一对振幅调制的正弦输出上。然后可捕获和解码这些输出,以产生可由数字电机控制器使用的绝对转子角度的数字形式。实现分解器接口的一种通用方法是使用独立的分解器到数字转换器(如TI的...
应用。具有更快启动时间的Δ-Σ模数转换器是解决之道。更高分辨率的Δ-Σ模数转换器减少了空气断路器(ACB)不同型号所用的硬件数量,并缩短了设计周期。&&空气断路器参考设计(TIDA-00661)的高分辨率快速启动模拟前端重点解决关键的断路器要求。您还可以在塑壳断路器(MCCB)的设计解决方案中使用部分或全部解决方案。用于低电压应用的空气断路器
图1:高达6300A的SACE...
电池大小,并降低系统成本。&&实施我上面列出的相对简单的HCA功能时,若它们都需在一个单一的主锂亚硫酰氯或锂二氧化锰电池(能力处在900mAh至1.2AH范围)运行12年以上时,这将变得更具挑战性。电池若想获得如此寿命,需要一个专注HCA各个功能超低功耗的高度优化的硬件和软件设计。例如,一个集成的SAR ADC(若低功率的ADC模块可用)可以测量NTC元件或LMT70A CMOS...
图形AD,最高支持720X480@60fps的标清视频的硬件解码,BT656格式YCbCr 4:2:2数据流输出。
c) 外接1路DVI/VGA数字/模拟图像输出接口,通过前面板DVI-I接口(24+5针)输出,用于监控显示。DVI输出最高支持fps分辨率。
d)外接3组256MB DDR2 SDRAM用作数据缓存,每组DDR2可独立工作在250MHz时钟频率以上...
板卡可以实现2通道万兆光纤的高速采集、实时记录和宽带回放。该板卡为标准半高半长尺寸,适合于目前主流半高机箱的服务器或超微工作站。1.2 功能框图图1-1 板卡功能框图1.3 硬件指标q 标准PCI Express半高半长卡,适合于半高机箱。q 符合PCI Express Gen2.0规范,可选x1、x4或x8模式,理论带宽高达40Gbps。q 2路万兆光纤网络接口,最大支持10Gbps/lane线...
还是用硬件串口。查询太耗时间,中断的话,可能会影响一些在执行的时序。尽量还是用硬件串口。
[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=2080339&ptid=503012][color=#999999]迈尔风随 发表于
13:39[/color][/url][/size]
io口模拟串口的方式...
岗位职责:
1.参与项目需求分析,将用户需求转化成硬件设计需求;2.负责制定硬件开发计划;
3.负责硬件方案设计;
4.负责硬件原理图和PCB设计;
5.负责硬件电路板的焊接、调试和测试,以及系统测试和现场测试;
6.负责编写硬件设计相关开发文档;
岗位要求:1.至少熟悉以下CPU架构的一种: ARM cortex a8、X86、PowerPC 等;2.精通模拟电路、数字电路...
模拟硬件视频
模拟硬件创意
你可能感兴趣的标签
热门资源推荐1335人阅读
算法(65)
〖〗〖翻译〗如何编写模拟器原名: How To Write a Computer Emulator作者: Marat Fayzullin翻译: LuciferWon注释: ⒈ 重译的原因是因为原来 Nelson Chou 的译文为繁体版不符合大陆人的习惯,而且,他翻译的有错误。&&&&&&& ⒉ 不想向巴哈姆特网站申请转载,因为此站竟然将大陆的身份证号归到外国类中!反感!所以,重新翻译,而后会联系 Marat Fayzullin&&&&&&&&&&& 本人。&&&&&&& ⒊ 未经过作者和幻梦飞翔社区同意,不得转载本文!
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
大量的想编写模拟器而又不知道如何编写的人给我发来了邮件,为此,我写了这篇文章。当然,以下文章中的各种想法和意见都是我个人的意见,不应被当作编写模拟器的唯一途径。文章主要以 "解释型(直译型)" 模拟器("Interpreting" Emulators) 为主对象,而与其相对的 "汇编型(编译型)" 模拟器("Compiling" Emulators),因为我没有足够的相关的汇编技巧的经验,所以未涉及。当然,我也在文章中放置了一两个你能找到相关信息的链接。
如果,你认为这篇文章遗漏了什么,或是你想要更正,请发邮件通知我。但是,我不回答争论性的、愚蠢的和向我索要 Rom 镜像的问题。也许,这篇文章的资源列表中我错过了一些重要的 FTP/WWW,如果你知道一些站点有重要的资料,请通知我,如果还有其他的 FAQ 不包括在本文的范围内,也请告诉我。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
如何,你是否决定好要写一个模拟器软件?其实这很好,当然,也许这篇文章会帮到你,它包涵了编写模拟器时会遇到的常规性问题的解答。而且,他会为你描绘一幅模拟器内部运作的 "蓝图" ,让你在一定程度上有所遵循!
概要 什么才能够被模拟?什么是 " Emulation " ?和 " Simulation " 有何不同?模拟有专利的硬件合法吗?什么是 "解释型(直译型)" 模拟器("Interpreting" Emulators) ?和 "汇编型(编译型)" 模拟器("Compiling" Emulators) 有何不同?我要编写一个模拟器,我应该从什么地方开始呢?我应该使用哪种程序语言?我应该在何处找将要模拟的硬件的资料呢?
编写步骤我应该如何模拟 CPU 的工作原理?我应该如何处理被模拟的内存区的访问?周期性: 这是什么?
程序技巧如何优化 C 语言代码?什么是 Low/High - Endiness?如何是程序具有可移植性?为什么我应该使程序模块化?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++什么才能够被模拟?
基本上,只要内部具有微处理器的就可以。当然,仅仅一些或多或少有些弹性的程序才是我们感兴趣的,将要被模拟的。他们包括:电脑计算器家用游戏机大型街机其他
注释你能模拟的任一计算机系统是十分必要的,即使它十分的复杂(例如: Commodore Amiga Computer),而且模拟效果也许不好。〖翻译〗如何编写模拟器 &传说中的'HOW TO MAKE AN EMULATOR"
--------------------------------------------------------------------------------
作者: zchou (Nelson Chou) 看板: Emulator标题: 传说中的'HOW TO MAKE AN EMULATOR"时间: Sun Aug 16 13:05:15 1998
**********************************************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& **** 好象有很多人看过英文版的,趁着有点时间,顺手翻一下.不过还没有&& **** 写给原作者,有点像盗版的,实在不太好!&&&&&&&&&&&&&&&&&&&&&&&&&& **** 也许有地方翻的不好,主要是以意译为主,所以删改了一些句子,如果&& **** 有搞错原意的地方,还请各位多多辅助,为需要知道如何写模拟器的&&& **** 人提供信息.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ****&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& NELSON CHOU&&&&&&&&&&&&&&&&&&&& ****&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& **********************************************************************
HOWTO:写一个计算机模拟器
禁止未授权散布.可以链接到这文件,但是不要复制它.
如何写一个计算机模拟器 - Marat Fayzullin(How To Write a Computer Emulator by Marat Fayzullin)
我收到一大堆E-MAIL,来自想写模拟器但是不晓得从哪里开始着手的朋友,所以我写了这个文件.以下的任何意见及建议都只是我自己的想法,不应该被当作唯一写模拟器的方式!本文主要适用于直译式模拟器("interpreting" EMULATOR),与其相对的是编译式模拟器(" compiling " EMULATOR),因为我没有很多重编译技巧(recompilation techniques)的经验!它也指引了一,两个可以找到这些技巧数据的地方!如果你觉得本文错过了什么或者哪里要更正,请E-MAIL给我你的意见!我不回答激愤的,愚蠢的,和要求ROM IMAGE的问题.也许我错过一些重要的 FTP/WWW地址在这文件的结尾,假如你知道足以放在那边的数据,请告诉我.如果有其他FAQ不在本文内的,也请告诉我.
这文件也已经由Bero翻译成曰语.
前言怎样,你决定写一个软件模拟器吗?很好的,这篇文件或许能给你一些帮助!它涵盖了一些当人们问及如何写模拟程序时的通用技术性问题.它同时也提供你模拟器内部运作的蓝图,让你多少能够根据循!
提纲:什么能被模拟呢?什么是" emulation "? 和"simulation "有何不同?模拟有专利的硬件合法吗?什么是"interpreting emulator"? 和"recompiling emulator" 有何不同?我想要写一个模拟器.我该从哪开始?我该使用何种程序语言?我要从哪里找到被模拟的硬件的数据?
制作步骤我该如何模拟一个CPU?我该如何处理被模拟内存(emulated memory)的访问?周期行程(Cyclic tasks):这是什么?程序写作技巧我该如何优化C代码?什么是LOW/HIGH-ENDIANESS?如何使程序具有可携性?为什么我应该使程序模块化?其他
什么能被模拟?&& 基本上,任何要被模拟的系统都有一个微处理器.当然,只有运行较具弹性或较不具弹性程序的设备是我们感兴趣模拟的.包含:计算机.计算机.家用游戏平台.大型电玩.其他.记下你能模拟的任何计算机系统是必要的,即使它十分复杂(如Commodore Amigacomputer).虽然这样的模拟程序性能也许不太好.
什么是" emulation "? 和"simulation "有何不同?" emulation "是意图模拟一项设备的内部设计."simulation "是意图模拟一项设备的功能!譬如,一个程序能够模拟"小向导(PACMAN)"大型电玩硬件和运行真正"小向导(PACMAN)"ROM,这个程序就是一个EMULATOR!一个为了你的电脑而写的"小向导(PACMAN)"游戏,但使用图像类似于真正的大型电玩,这个游戏程序就是一个 SIMULATOR!
模拟有专利的硬件合法吗?这文件事其实是界于一个灰色地带,模拟有专利的硬件似乎是合法的,但是不包含非法使用这些用于有专利硬件上的信息!你应该也发现到伴随着模拟器一起散布SYSTEM ROMS(BIOS,或其他)是违法的,如果这些ROM是有版权的!
什么是"interpreting emulator"? 和"recompiling emulator" 有何不同?有三种基本规划可以用以设计一个模拟器.他们也能相互结合以获得最佳效果!
直译型(Interpretation)一个模拟器运行的方式是从内存一个BYTE一个BYTE的读入被模拟的代码,再解码这被模拟的代码,再运行适当的命令在被模拟的寄存器,内存,及I/O,这种模拟器就称为直译型模拟器!这类的模拟器一般的算法如下:
while(CPUIsRunning)&&&&&& /* 利用一个检查CPU是否运行的旗标的无限循环 */{Fetch OpCode&&&&&&&&&&& /* 抓取运算码 */Interpret OpCode&&&&&&& /* 解译运算码 */}这种方式的优点包含易于除错,具可携性,易于同步(synchronization,你可以简化计算所经过的时序周期,并且固定你的模拟器在同一周期数的延迟)
明显的缺点就是性能.直译型模拟器花费相当多CPU时间,并且你可能需要十分快的计算机来运行你的程序,才能获得尚可的速度.
静态重编译型(Static Recompilation)在这个技巧中,你试图将一个由被模拟代码写成的程序,翻译成你的计算机所使用的汇编语言码.结果将成为一个无须任何特殊工具就可以在你的计算机运行的可执行文件.静态重编译型模拟器听起来似乎不错,不过这通常并不可行的!例如,你不能完全先行编译会自己修正的代码(self-modifying code),因为不运行这些代码,是不可能知道它们将会变成什么的!为了避免这种状况,你也许可以将直译型模拟器或动态重编译型模拟器与静态重编译型模拟器组合起来!
动态重编译型(Dynamic Recompilation)动态重编译型模拟器与静态重编译型模拟器在本质上是相同的,只不过动态重编译型模拟器出现在程序运行时.为了代替一次就重编译好所有的代码,我们可以只在遇到"CALL"或者"JUMP"命令时,立即再作一次重编译任务!为了增加速度,这种技巧也能与静态重编译型模拟器组合使用.你能在这里找到更多有关动态重编译型模拟器的数据: white paper by Ardi,creators of the recompiling Macintosh emulator.
我想要写一个模拟器.我该从哪开始?为了写模拟器,你必须要有良好的计算机程序设计及数码电子学的一般知识背景.有汇编语言程序设计的经验亦十分重要.你先要做到:选择所使用程序设计语言.找到所有有关被模拟的硬件的数据.重写一个CPU的模拟器或者取得已写好的CPU模拟器代码.最少先部份地写一些草拟码来模拟硬件的一部份,由这点看来,在写模拟器时同时作一个拥有允许暂停模拟及看看这个程序正在干嘛这种功能的小型内置除错器,这样是非常有帮助的.同时你也需要被模拟系统所使用的汇编语言的反组译程序.如果找不到现成的反组译程序,就自己作一个.试着在你的模拟器上运行程序看看.使用反组译程序及除错器了解程序是如何使用硬件的,并且适当的调整模拟器的代码.
我该使用何种程序语言?最明显的选择方案是 C 及 汇编语言.以下是他们的优缺分析:汇编语言优:1.可以产生较快速的代码.&&&& 2.用以模拟的CPU的寄存器可以直接用来保存被模拟的CPU寄存器的数据.&&&& 3.许多运算码可以用相似的用以模拟的CPU的运算码来模拟.缺:1.这种代码没有可携性,也就是不能在不同架构的计算机上运行.&&&& 2.代码的除错与维护不太容易.C优:1.可以做成具可携性的代码,如此便能使用在不同的计算机及操作系统.&&&& 2.相对来说,代码的除错与维护较为容易.&&&& 3.可以很快的测试对真实硬件如何运作的不同假设.缺:一般而言,C 代码通常比纯汇编语言代码慢一些.
对于写一个可运作的模拟器来说,对所选择的程序语言有深入的认识是绝对必要的,因为这是十分复杂的计划,并且你的代码应该尽可能的优化使之执行的更快!说的明白一点,作计算机模拟器不应是一个学习程序语言的计划.
我要从哪里找到被模拟的硬件的数据?以下列出来的地方,你也许想要看看.Newsgroupscomp.emulators.misc这是一个有关计算机模拟一般性讨论的Newsgroup.许多模拟器作者也阅读这里的讨论,不过这里的废话多了一点!在你想刊登问题在这个讨论区之前,请先看看这里: c.e.m FAQ
comp.emulators.game-consoles跟comp.emulators.misc差不多,不过特别注重家用游戏平台模拟器.在你想刊登问题在这个讨论区之前,也请先看看这里: c.e.m FAQ
comp.sys./emulated-system/comp.sys.*类阶层包含许多特殊计算机系统的讨论区.
藉由读这些newsgroups,你可以获得很多的有用的技术性信息.典型的例子如:comp.sys.msx&&&&&& MSX/MSX2/MSX2+/TurboR computerscomp.sys.sinclair Sinclair ZX80/ZX81/ZXSpectrum/QLcomp.sys.apple2&&& Apple ][etc.
郑重呼吁,先看看这些FAQ在你想在这些新闻讨论区发问之前.puters rec.games.video.classic
FTP ---- 包含游戏平台及游戏程序设计,位置在 Oulu , Finland
----- 大型电玩硬件数据库
----- 计算机历史及模拟器数据库,位置在 KOMKON
WWW comp.emulators.misc FAQ My HomepageArcade Emulation Programming Repository
Emulation Programmer's Resource〖翻译〗如何编写模拟器我该如何模拟一个CPU?首先,如果你只需要模拟一个标准的 Z80 或 6502 CPU,你可以用我写的CPU模拟器! http:// 请先确定一下使用条件,在加入它们之前.
对于那些想要写自己的CPU模拟核心或者对于CPU模拟核心感兴趣的人,以下我提供一个典型C语言CPU模拟器.在真实的模拟器之中,你也许想要保留它的一部份,或者加入一部份到你自己的CPU模拟器.
Counter=InterruptPPC=InitialPC;
for(;;){OpCode=Memory[PC++];Counter-=Cycles[OpCode];
switch(OpCode){&&& case OpCode1:&&& case OpCode2:&&& ...}
if(Counter&=0){&&& /* 检查所发生的中断并运行这些中断 */&&& /* 周期行程(Cyclic tasks)置于这里 */&&& ...&&& Counter+=InterruptP&&& if(ExitRequired)}}
首先,我们要给定一个初值到CPU周期计数器"Counter",及程序计数器"C"!
Counter=InterruptPPC=InitialPC;
"Counter"包含CPU周期数到下一个可能的中断.注意那些当"Counter"到期时,不需要发生的中断:你可以使用在很多其他用途上,例如将计时器同步化,或者更新屏幕上的扫描线."C"包含我们所模拟的CPU将读入的运算码内存地址.
在初值给定后,我们就可以开始主要的循环:
for(;;){也可以用这样的方式,
while(CPUIsRunning){"CPUIsRunning"是一个布尔变量.这有相当的优点,你可以随时藉由设置"CPUIsRunning"为"0"终止这个循环.不幸的,每次循环经过都必须检查这个变数,这将花费很多CPU时间,应该尽量避免这样的方式.也不要做这样的循环:
while(1){因为有些编译器会产生检查"1"是不是表示布尔"true"的代码.你一定不希望编译器产生这种每经过循环一次都要做一次不必要任务的代码.
现在,我们进到循环了,第一件事就是先读入下一个运算码,同时更改程序计数器"C".
OpCode=Memory [ PC++ ] ;
注意这里,虽然这是从被模拟内存中读入命令的最简单及最快的方式,不过这不一定可行就是.更通用的访问内存的方式稍后会介绍.
在抓取完运算码之后,我们减少CPU周期数"Counter",减少的数量是这个运算码所需要的周期数.
Counter-=Cycles [ OpCode ] ;
"Cycles [ ]"表格包含了每个运算码的CPU周期数.提防某些运算码可能因为参数的不同而有不同的周期数,例如条件跳跃或者副程序呼叫.虽然在程序中稍后能够再调整.
现在到了解译运算码及运行运算码的时候了:
switch(OpCode){一般人有个误解,以为用switch()结构是没有效率的,因为这会编译成一串if() ... else if() ...的叙述.当CASE很少时,这倒是真的.不过在大型结构中(超过100-200个以上的CASE)会编译成一个"JUMP TABLE",这反而十分有效率.有两种选择方式来解译运算码.第一种方式是作一个函数表(FUNCTION TABLE)并且呼叫适当的函数.这种方式比用 SWITCH() 还没效率,因为函数呼叫花费更大.第二种方式是作一个选项卡表(LABEL TABLE)并且利用"GOTO"叙述.这种方式比用 SWITCH() 有效率一点,不过只在编译器支持"预先计算选项卡(precomputedlabels)这项功能才能运行.有的编译器不允许你做一个选项卡地址数组(array oflabel addresses).
在我们成功的解译并运行运算码之后,再来是检查需不需要任何岔断.在这个时刻,你也可以完成任何需要与系统时钟同步的行程.
if(Counter&=0){/* 这里运行检查岔断及完成其他硬件模拟的步骤 */...Counter+=InterruptPif(ExitRequired)}这些周期行程(CYCLIC TASKS)稍后会帮助.
注意这里,我们并不是简单的使用" Counter=InterruptP ",而是使用" Counter+=InterruptPeriod ":这将使得周期计算更为精密,因为在"Counter"中可能负的周期数出现.
也注意这里:
if ( ExitRequired )
因为每经过一次循环就检查一次是否离开程序,这样满浪费的,我们只在"Counter"到期时做这项任务:这样还是会离开模拟器,当你设置"ExitRequired=1"时,不过这不会花费太多CPU时间.
我该如何处理被模拟内存(emulated memory)的访问?访问被模拟内存最简单的方式是如同一块平坦的byte(words或其他)数组,琐碎的处理它,如:
Data=Memory[Address1]; /* 从 Address1 读入 */Memory[Address2]=D /* 写入到 Address2 */
如此简单的内存访问实际上并不总是可能的,原因如下:
分页内存(Paged Memory)寻址空间可能是零散的在于可切换页(switchable pages,或称BANK).这常被做为扩充内存的方式,当寻址空间是小的(64KB).
对映内存(Mirrored Memory)一块内存区域可在几种不同的地址访问.例如,你写入到位置 $4000 将也出现在 $6000 及 $8000.ROM 也可能被映射到不完全的地址解码.
ROM 保护(ROM Protection)某些卡匣型的软件(如 MSX 游戏)会尝试写入到自己的ROM,并且在写入成功时拒绝再继续运行.通常这是为了防拷.为了使这样的软件在你的模拟器上继续运行,你应该阻止写入到ROM中.
Memory-Mapped I/O在这种系统中,可能有 Memory-Mapped I/O 设备.访问到这样的内存位置会产生"特殊效果",因此这样的访问方式应该要追踪.
为了应付这种问题,我们介绍两种映射的函数:
Data=ReadMemory(Address1); /* 从 Address1 读入 */WriteMemory(Address2,Data); /* 写入到 Address2 */
所有特殊处理,如页访问,对映,I/O处理等等,都可以由这些函数处理.
ReadMemory() 及 WriteMemory() 两种函数在模拟过程中占用很大一部份,因为他们很常被呼叫.所以,他们一定要尽可能的做得有效率.这里是用以访问分页寻址空间的函数示例:
static inline byte ReadMemory(register word Address){return(MemoryPage[Address&&13][Address&0x1FFF]);}
static inline void WriteMemory(register word Address,register byte Value){MemoryPage[Address&&13][Address&0x1FFF]=V}
注意"inline"这个关键字.他告诉编译器将函数直接展开到代码,而不是以函数呼叫的方式.如果你所用的编译器不支持"inline"或"_inline",尝试利用"static function"来定义这样的函数:某些编译器(如 WATCOM C ),会以INLINE的方式优化短的"static function".
在大部分的情况下,ReadMemory() 函数比 WriteMemory() 函数使用的频率要高出许多倍,你也应该谨记在心.所以,把 ReadMemory() 函数代码尽可能写得的比 WriteMemory() 函数短,这样是很值得的.
在内存对映(memory mirroring)上还有一个小小的重点:有此一说,许多计算机都有对映RAM(mirrored RAM),你可以发现某个数值写入到某个地址却也将会出现在其他地址.你可以在 ReadMemory()函数中处理这样的状况,但这实在不太值得,因为 ReadMemory()函数呼叫的频率实在大过WriteMemory() 函数(译按:原意应该是"因为有很多地址都能读到同一个数字,所以只要读取一个地址就可以,不要读取好几个地址才决定这个数字,ReadMemory() 函数使用的频率太多,多加入不必要的代码将严重损及效率")更有效率的方式将是撰写 WriteMemory() 函数时加入内存对映的功能.〖翻译〗如何编写模拟器周期行程(Cyclic tasks):这是什么?周期行程是在模拟机器中应该要定期处理的事情,例如:屏幕更新(Screen refresh)VBlank 及 HBlank 岔断更新计时器(Updating timers)更新音效参数(Updating sound parameters)更新键盘/摇杆状态(Updating keyboard/joysticks state)其他为了模拟这些行程,你应运行在 2.5 MHz的?50Hz 的更新频率( PAL 图像盲郱?,VBlank岔断应该以这样社W率发生
= 50000 CPU cycles
现在,如果我们假设屏幕是256条扫描线,但是只有212条扫描线是真的显示在屏幕上的(i.e. 剩下44条被 VBlink 吃了),我们得到你的模拟器应当花费在更新每条扫描线是该以适当的CPU周期数固定它们.例如,如果CPU建议速度,屏幕显示使术? ~= 195 CPU cyles
在这之后,你就应该产生一次 VBlink 岔断,并且直到 VBlink 完成前,不做任何事.(i.e.
( 256-212 ) * = 44* ~= 8594 CPU cycles
小心的计算每个行程所需的CPU周期数,然后把他们的最大公约数定成"InterruptPeriod(中断周期)"并且固定所有其他行程到"InterruptPeriod"(在每次"Counter"到期时,这些行程不需要运行).
我该如何优化C代码?首先,正确的选择编译器所提供的优化选项能增加额外的代码性能.在我的经验中,以下的选项组合可以给你最佳的运行速度:
Watcom C++&&&&& -oneatx -zp4 -5r -fp3GNU C++&&&&&&&& -O3 -fomit-frame-pointerBorland C++
如果你发现有其他更好的选项组合,不管是以上的编译器或者其他不同的编译器,请你告诉我.
一些循环展开(loop unrolling)的小小建议:将编译器优化的"循环展开"选项设成"on"可能是很有用的.这项选项将尝试转换短循环变成平滑的程序片段.我的经验显示,虽然,这项选项不会产生任何性能改进.但是设置成"ON"时也可在某些极特殊的条件中中断你的代码.
优化C的原始代码比选择编译器选项稍微来得好,并且就一般而言,用编译器编译代码这是一个与CPU有关的优化方式.几个一般性适用于所有CPU规则如下.不要把它们的运作方式当做绝对的事实,因为你的用途可能不同:
使用程序分析工具(profiler)!你的程序在程序分析工具程序(记住GPROF)下运行的情形会显示很多很好的事情,是以前你从未怀疑的.你会发现,看起来微不足道的程序片段运行的频率比其他部份多的太多了,并且使整个程序慢下来.将这些程序片段优化或者改以汇编语言撰写会大幅增加性能.
避免使用C++避免使用任何结构,这会强迫使用C++编译器代替C编译器去编译你的程序:C++编译器通常会产生额外的代码.
整数的尺寸(Size of integer)尝试只使用一种CPU所支持的基底整数尺寸,i.e. 整数(int)尺寸相对于"short" 或"long"整数的尺寸.如果使用混合的整数尺寸,这将使编译器产生一堆不同整数长度间转换的代码.这也会增加计忆体访问时间,因为某些CPU当以基底整数读写数据时会因为对齐基本基底地址边界而使运行速度加快.
寄存器定位(Register allocation)在每一区中,尽可能的减少使用变量,把最常使用的变量声明为寄存器变量"register variable"(虽然大部分新的编译器可以自动地把变量变成寄存器变数 ).这在拥有较多通用寄存器的CPU(PowerPC)比在只有少数专用寄存器的CPU( Intel 80x86)更有意义.
展开小的循环(Unroll small loops)如果你想要使小循环在很短的时间内运行,以手动的方式展开小循环成为平滑的程序片段会是个好主意.看看上面有关自动循环展开的讨论.
字节移位(Shifts) VS. 乘/除法当你需要乘或除以2的次方数时,应该以字节移位代替( J/128==J&&7 ).在大部分CPU下,这些方式会运行得较快.同样的,使用字节"AND"运算代替取余数的运算( J%128==J&0x7F ).
什么是LOW/HIGH-ENDIANESS?所有的CPU一般都可分成两种,这与他们如何在内存保存数据有关.
High-endian CPU这种CPU是把一个word的higher byte放在前面的保存方式保存数据.例如,如果要保存 0x 到这样的CPU,这块内存看起来会像这样:
&&&&&&&&&&&&&&&&&&&&& 0 1 2 3&&&&&&&&&&&&&&&&&&&& +--+--+--+--+&&&&&&&&&&&&&&&&&&&& |12|34|56|78|&&&&&&&&&&&&&&&&&&&& +--+--+--+--+
Low-endian CPU这种CPU是把一个word的lower byte放在前面的保存方式保存数据.跟前面一样的例子在这种CPU会看起来非常不一样:
&&&&&&&&&&&&&&&&&&&&& 0 1 2 3&&&&&&&&&&&&&&&&&&&& +--+--+--+--+&&&&&&&&&&&&&&&&&&&& |78|56|34|12|&&&&&&&&&&&&&&&&&&&& +--+--+--+--+
典型的High-endian CPU的例子是 6502 and 65816 ,Motorola 680x0 系列,PowerPC ,及 Sun SPARC .Low-endian CPU包含Zilog Z80,大部分INTEL晶片(包含 ),DEC Alpha,等等.
当你写一个模拟器,你必须注意被模拟及模拟别人的CPU是何种ENDIANESS,我们说,你想要模拟Z80 CPU,这是一个Low-endian CPU,也就是保存16-BIT WORD时LOWER BYTE在前面.如果你使用的是Low-endian CPU(例如,INTEL 80x86),在这个例子,每件事都发生的很正常.如果你使用的是High-endian CPU( PowerPC),突然就出现了放置16-bit Z80数据到内存的问题.如果你的程序必须在两种机器下运行,你需要某种方式感觉endianess.
一种处理 endianess问题的方法如下:
typedef union{
short W;&&&&&&& /* Word 访问 */
struct&&&&&&&&& /* Byte 访问... */{#ifdef LOW_ENDIAN&&& byte l,h;&&&& /* ...在 low-endian 机器 */#else&&& byte h,l;&&&& /* ...在 high-endian 机器 */#endif} B;
正如你所看到的,一个"WORD"的数据利用 W 可以整个访问.每次你的模拟程式需要分开访问BYTE时,你可以使用 B.l 及 B.h 访问数据.如果你的程序将在不同平台编译时,在运行任何真正重要的事情时,你可能先想要测试一下它是否以正确的endianess方式编译的.
这里是这种测试的一种方式:
T=(int *)"/01/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0";if(*T==1) printf("This machine is high-endian./n");else&&&&& printf("This machine is low-endian./n");
如何使程序具有可携性?正在写.
为什么我应该使程序模块化?正在写.
copy Copyright by ..Marat Fayzullin[fms@cs.umd.edu]
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2573395次
积分:32949
积分:32949
排名:第107名
原创:275篇
转载:2345篇
评论:214条
(30)(4)(27)(78)(31)(16)(27)(44)(7)(11)(39)(8)(58)(4)(13)(8)(16)(82)(74)(85)(9)(28)(5)(11)(13)(2)(2)(6)(9)(33)(8)(15)(3)(4)(1)(1)(8)(61)(10)(5)(1)(3)(40)(44)(21)(19)(11)(1)(1)(1)(1)(3)(14)(48)(48)(2)(14)(53)(12)(12)(17)(9)(25)(15)(17)(9)(18)(18)(2)(6)(1)(14)(8)(12)(23)(26)(14)(2)(13)(17)(53)(13)(2)(6)(5)(15)(10)(19)(14)(15)(5)(14)(28)(15)(17)(22)(3)(18)(9)(10)(13)(21)(22)(110)(78)(81)(21)(23)(42)(3)(5)(19)(16)(31)(1)(7)(14)(9)(12)(27)(30)(10)(19)(12)(6)(13)(17)(18)(23)(28)(19)(12)(5)(3)(5)(5)(5)(21)(11)(39)

我要回帖

更多关于 夜神模拟器 脚本编写 的文章

 

随机推荐