N开头的genymoton模拟器联网器

查看:77763|回复:166
最近思科内部的CiscoIOU(IOS Over Unix)遭到泄露,也炒的很火,据说cisco内部人员用它来测试新出的IOS的feature。它最牛的特点是用它跑N台虚拟路由器对cpu占用也没多少。这点就直接秒杀掉目前所有的模拟器。由于刚刚放出来没什么资料,总结了下网上的经验。
现在有2种整合版本可以下载(下载地址自己google),一种是撒加的CDlinux-IOU.iso,和flyxj的cisco-iou-livecd-v1.0,2者区别就是撒加的可以自己任意搭拓扑,自己搭个IE机架都行。flyxj的拓扑已经搭好由6台路由器组成。
不懂的可一看这个文档:
收费附件: CDLinux-IOU_2.0使用指南.pdf
1、该版本依旧是支持在虚拟机里运行的
2、光盘启动后将自动开启SSH,方便使用SecureCRT连接到虚拟机做IOU实验
3、默认的root么有密码,运行通过SSH连接并允许空密码登陆
4、支持保存用户的IOU配置
5、支持每次启动后自动更新CDLINUX的系统时间
6、自定义网络TOP&&
PS:先前发布的版本将不再提供下载了,下一步的计划是用别的版本来做一个可以安装到硬盘上版本,当然不是基于CDLINUX的,等测试完成了再透露
还考虑使用VBOOT,可以在电脑启动的时候直接启动到VHD文件里,做实验,也能保存配置
以上是撒加版本!
下载地址:
CDlinux-IOU.iso
思科IOU模拟器视频教程下载
1.使用 VMWARE 增加一块硬盘
2.下载 CDlinux(7R).iso CDlinux(6R).iso
3.VMWare以CDlinux(7R).iso 开启
详细情况请看录像
CDLinux-IOU-2.avi
CDLinux-IOU-1.avi
在此我们学习一下哈!!!!
先停掉原本的 7 台 Router
killall i86bi_linux-adventerprisek9-ms
查看硬盘分区情况
为硬盘建立分区
fdisk /sda
格式化分区 ext2
mke2fs /dev/sda5
将分区挂载到 /mnt
mount /dev/sda5 /mnt
挂载光盘到
/media/CDlinux
mount /dev/cdrom /media/CDlinux
将光盘全部复制到目前目录下
cp -a /media/* .
将复制过来的 cdl.md 和 cdl.tgz 删除
rm -rf CDlinux/CDlinux/extra/CiscoIOU-cdl.md
rm -rf CDlinux/CDlinux/local/BX2AA-cdl.tgz
创建 iou 目录, 给我们的
i86bi_linux-adventerprisek9-ms 和拓扑文件 NETMAP 使用
创建 CiscoIOU 目录, 用来挂载原本的 CiscoIOU-cdl.md 复制其中文件时要使用
mkdir CiscoIOU
创建 iso 目录, 用来存放最终的 CDlinux.iso
删除 /tmp 目录
rm -rf /tmp
建立 /tmp 链接
ln -s /mnt/iso /tmp
将光盘 CiscoIOU-cdl.md 挂载到 CiscoIOU 目录
mount -t squashfs -o loop /media/CDlinux/extra/CiscoIOU-cdl.md CiscoIOU
复制 CiscoIOU 内所有文件到 iou
cp -a CiscoIOU/root iou
解开光盘 BX2AA-cdl.tgz 文件
tar -zxvf CDlinux/CDlinux/local/BX2AA-cdl.tgz
其实我个人觉得
i86bi_linux-adventerprisek9-ms 比较少出现 IOU ???? exit 的问题, 所以我就用他.
若要省空间和时间顺便删了 i86bi_linux-ipbase-ms i86bi_linux-tpgen+ipbase-ms.PAGENT.4.7.0 吧!
i86bi_linux-ipbase-ms i86bi_linux-tpgen+ipbase-ms.PAGENT.4.7.0
rm -rf /mnt/CiscoIOU/root/i86bi_linux-ipbase-ms
rm -rf /mnt/CiscoIOU/root/i86bi_linux-tpgen+ipbase-ms.PAGENT.4.7.0
切换目录到 iou/root (本教程的目的相关文件所在)
cd iou/root
创建各机架所要用的目录
mkdir LAB01 LAB02 LAB03 LAB04 LAB05 LAB06 LAB07 LAB08 LAB09 LAB10
将 license 文件复制到各目录
cp iourc LAB01
cp iourc LAB02
以下省略....
创建 NETMAP 文檔(亦可使用vi编辑器)
echo &:0/0 2:0/0&&LAB01/NETMAP
echo &1:0/3 11:0/1&&&LAB01/NETMAP
echo &3:0/0 4:0/0&&LAB02/NETMAP
echo &3:0/3 11:0/2&&&LAB02/NETMAP
创建 lab01 脚本
echo &cd LAB01&&lab01
echo &../wrapper-linux -m ../i86bi_linux-adventerprisek9-ms -p 2001 -- -e 1 -s 0 -n 1024 -C -m 128 -R -U -N 1 &&&&lab01
echo &../wrapper-linux -m ../i86bi_linux-adventerprisek9-ms -p 2002 -- -e 1 -s 0 -n 1024 -C -m 128 -R -U -N 2 &&&&lab01
echo &../wrapper-linux -m ../i86bi_linux-adventerprisek9-ms -p 2011 -- -e 1 -s 0 -n 1024 -C -m 128 -R -U -N 11 &&&&lab01
echo &show&&&lab01 &====== 您可以自行将此机架拓谱显示出来
echo &cd ..&&&lab01
创建 lab02 脚本
echo &cd LAB02&&lab02
echo &../wrapper-linux -m ../i86bi_linux-adventerprisek9-ms -p 2003 -- -e 1 -s 0 -n 1024 -C -m 128 -R -U -N 3 &&&&lab02
echo &../wrapper-linux -m ../i86bi_linux-adventerprisek9-ms -p 2004 -- -e 1 -s 0 -n 1024 -C -m 128 -R -U -N 4 &&&&lab02
echo &../wrapper-linux -m ../i86bi_linux-adventerprisek9-ms -p 2011 -- -e 1 -s 0 -n 1024 -C -m 128 -R -U -N 11 &&&&lab02
echo &cd ..&&&lab02
大家应该都知道就用两个代表一下
以下略....
LAB 的脚本
echo &killall i86bi_linux-adventerprisek9-ms&&off
将脚本给予 执行 权限
chmod a+x lab*
将脚本给予 执行 权限
chmod a+x off
可使用编辑器编辑 rc.local 符合自己需要, 显示拓扑的部份可清除 用 /root/show 替换
cat etc/rc.d/rc.local
可使用编辑器编辑 show 符合自己需要, 方便显示拓扑
cat iou/root/show
都准备好后将 etc 目录打包到 CDlinux/CDlinux/local/BX2AA-cdl.tgz
tar -czvf CDlinux/CDlinux/local/????????-cdl.tgz etc
将 iou 包起来放到 CDlinux/CDlinux/extra/CiscoIOU-cdl.md 虚耗点时间等待
mksquashfs iou CDlinux/CDlinux/extra/CiscoIOU-cdl.md
切换到 CDlinux
cd CDlinux
重新包 iso 文件
./mkisofs.sh
光盘镜像在 /mnt/iso
ls -l /mnt/iso
关于下载地址,如果有问题请联系我!
09:50, 下载次数: 1854
, 售价: 无忧币 2
又可以下载了
本帖最后由 zhang45xiang 于
09:53 编辑
入则恳恳以尽忠,出则谦谦以自悔...
初级工程师
这个要支持了。。。。
初级工程师
上面的那些全部没法下载了。。。
引用:原帖由 yahooocomcn 于
11:02 发表
上面的那些全部没法下载了。。。 经过测试,可以!
入则恳恳以尽忠,出则谦谦以自悔...
初级工程师
引用:原帖由 zhang45xiang 于
11:07 发表
经过测试,可以!
(69.26 KB)
第一个我下载时失败。。显示没资源。。。第二个和第三个干脆都不让下载了。。显示内容如上。。不知道是不是只有我这会这样。。
助理工程师
试试这个& &好玩不
中级工程师
要是L2的也能用就爽了~·
奋斗在路上!有你从不寂寞!
提示: 作者被禁止或删除 内容自动屏蔽
IOU很强大啊啊& &下来试一试
思科技术狂热分子
祥子不错嘛,看来我out了,这东西我才第一次听说,能不能上传些图片讲解下
引用:原帖由 独钩寒江雪 于
23:23 发表
祥子不错嘛,看来我out了,这东西我才第一次听说,能不能上传些图片讲解下 呵呵,所以搬过来给你看看啊,呵呵
入则恳恳以尽忠,出则谦谦以自悔...
真是好东西,要强烈支持了
中级工程师
回复楼上那些不能下载115网盘的
1.先点击进入下载页面
2.在下载页面输入如下代码:
& && && &&&javascript:MoveMyFile.Show();
3.跳出转存到自己的网盘,然后到自己网盘下载即可
&&不错的东西 !
版主&&这个可以用不同的IOS还是只能用镜像中提供的IOS?
助理工程师
very goodvery goodvery good
引用:原帖由 tdj7691 于
13:21 发表
版主&&这个可以用不同的IOS还是只能用镜像中提供的IOS? 只能用镜像里的啊,文档有说明的
入则恳恳以尽忠,出则谦谦以自悔...
支持一下。
助理工程师
我已经启动CDlinux-IOU了,但是怎样我才能登陆到路由器上面。指点一下吧!大师
(14.01 KB)
下载来看看热门搜索:
新游戏推荐经典单机游戏好玩的游戏中文单机游戏拳皇97,是一款SNK公司发布于1997年的街机格....《三国战纪:风云再起》是在三国战纪正宗plus基....《拳皇97 The King of Fighters 97》是著名的....西游释厄传/西游记《拳皇97风云再起》是《拳皇97》的修改版,可以直....《永远的超级玛丽》看到游戏的名字很多人就会....VisualBoy Advance《合金弹头》是日本SNK公司推出的一系列2D横板....拳皇97,是一款SNK公司发布于1997年的街机格....《三国战纪:风云再起》是在三国战纪正宗plus基....《拳皇97 The King of Fighters 97》是著名的....西游释厄传2西游释厄传/西游记《拳皇97风云再起》是《拳皇97》的修改版,可以直....《永远的超级玛丽》看到游戏的名字很多人就会....VisualBoy Advance
圆桌骑士(Knights of the R....侍魂II - 真侍魂霸王丸地狱变《A级方程式赛车》是一款赛车街机模拟游戏,在....街头篮球本作是一款讲述英雄救美的街机动作游戏,主角....枪战街机-游迅小游戏合集《Guilty Gear XX # Reload》采用了全新的作战....天开眼拳皇97,是一款SNK公司发布于1997年的街机格....《拳皇97 The King of Fighters 97》是著名的....西游释厄传2《三国战纪:风云再起》是在三国战纪正宗plus基....《三国战纪》是台湾d象电子公司(IGS)所开发。....三国战纪全集西游释厄传/西游记进入游戏后可以按下F7键读取已经预先设置好....
推荐游戏&BEST-GAMES
《合金弹头》是日本SNK公司推出的一系列2D横板....
《合金弹头》是日本SNK公司推出的一系列2D横板射击过关游戏。Metal Slug系列是ARC历史上唯一可以用一个几乎不变的引擎连作9部的游戏。SNK系列是硬派射击ACT超A级作品,一部2D的ARC作品达到如此的程度才真正算得上登峰造极....
拳皇97,是一款SNK公司发布于1997年的街机格....
拳皇97,是一款SNK公司发布于1997年的街机格斗游戏,在国内非常受欢迎,相比拳皇前三个版本各方面均有较大改进,是拳皇系列的成熟之作。也有一些经过修改的版本。
《拳皇97风云再起》是《拳皇97》的修改版,可以直....
《拳皇97风云再起》是《拳皇97》的修改版,可以直接选择到大蛇和鬼八神等魔化人物的。
进入游戏后可以按下F7键读取已经预先设置好....
进入游戏后可以按下F7键读取已经预先设置好的存档,激活了无限投币(家用模式),开启了血腥模式和隐藏人物的选择;如此这般就可以同时使用模拟器的金手指和UNI-BIOS内置的金手指,互不干扰(UNI-BIOS的主控权高于标准的BIOS);如果对BIOS和金手指的操作比较陌生,就用直接读取存档的这种方法,使用的时候请注意。
《三国战纪:风云再起》是在三国战纪正宗plus基....
《三国战纪:风云再起》是在三国战纪正宗plus基础上的增强版。是根据中国四大名著之一的《三国演义》改编的商用游戏,目前有很多模式和版本。
西游释厄传/西游记
西游释厄传/西游记
《拳皇97 The King of Fighters 97》是著名的....
《拳皇97 The King of Fighters 97》是著名的格斗游戏。本系列的格斗游戏各个都是精品,这个《拳皇97》更是精品中的精品,本人认为是kof系列最受欢迎的作品,不管是在街机还是家用机还是模拟器上,都有无数fans。最经典的kof97,大家决不能错过。
MAME32 Plus!
MAME32 Plus!
炸弹人机皇版(Neo Bomberman)
炸弹人机皇版(Neo Bomberman)
三国志2霸王的大陆
三国志2霸王的大陆
KOF98没有单独的故事情节,是单纯的体会对战....
KOF98没有单独的故事情节,是单纯的体会对战乐趣的游戏。这场被称为“永不休战的梦之战”的作品将前面各代的人气角色聚集一堂,共有50多位角色可以选用,收录了KOF系列除了藤堂香澄、高尼茨、如月影二、大蛇以及96BOSS队之外的所有角色。
“三国战纪-乱世枭雄”是IGS在中国国内的代理....
“三国战纪-乱世枭雄”是IGS在中国国内的代理商基於三国战纪-风云再起的基础上开发的非官方增强版。
90年代初的可以四人同时进行的经典动作游戏....
90年代初的可以四人同时进行的经典动作游戏!共有五个角色可选,老大彼得潘、老二双刀、老三企鹅小子、老四娃娃和老五胖子,其中数老大、老四、老五较为厉害一些,另两个攻击力太差,单打通关不易,而用其它三人均可轻易通关;游戏的故事背景就是消灭邪恶的铁钩船长,主角们的放血绝招各有不同,不过威力并不大,耗血反而很多,所以较少人会有这招!这个游戏可以无限循环地打,高手都可以打N个小时以上的...
西游释厄传2
西游释厄传2
炸弹人(Neo Bomberman)
炸弹人(Neo Bomberman)
三国战纪全集
三国战纪全集
拳皇2008巅峰之战 游戏有88种角色可供选择,....
拳皇2008巅峰之战 游戏有88种角色可供选择,界面从DOS黑窗口方式进入,提示 y/n 按Y进入。默认玩家1的操作按键是 W、S、A、D键控制方向,T、Y、U、G、H、J 键为动作键,其它特技键自己探索。
三国战记2:群雄争霸
三国战记2:群雄争霸
《三国战纪》是台湾d象电子公司(IGS)所开发。....
《三国战纪》是台湾d象电子公司(IGS)所开发。根据中国四大名著之一的《三国演义》改编的游戏。目前有很多版本。《三国战记2:群雄争霸》是根据三国战纪2进一步改编制作的游戏。
《Guilty Gear XX # Reload》采用了全新的作战....
《Guilty Gear XX # Reload》采用了全新的作战系统,玩家可以施展觉醒必杀技将局势扭转。只要待新设的BURST能量棒变成MAX后,BURST字样便会闪烁不停,这时候就是使出觉醒必杀技的最佳时间。觉醒必杀技具有无坚不摧的威力,在....
西游记释厄传2
西游记释厄传2
话说大唐玄奘有感东土人士弛平太久眈於酒色....
话说大唐玄奘有感东土人士弛平太久眈於酒色财气导致瘴疠之气隐隐浮现、妖魔之辈纷至沓来,盛唐之业似若残烛三藏不愿与蜉蚁 且,誓发宏愿,治苍生之业、救万民之苦,遂告表圣皇西行取经之举以立民族千秋伟业。
豪血寺一族
豪血寺一族
三国志-中原之霸者
三国志-中原之霸者
VisualBoy Advance
VisualBoy Advance
这个游戏其实是个三合一的游戏,这也是奇迹三世界名称的由来!
这个游戏其实是个三合一的游戏,这也是奇迹三世界名称的由来!
日落骑士(Sunset Riders)西部牛仔
日落骑士(Sunset Riders)西部牛仔
电精 II / 电神魔傀 II / 守护将军
电精 II / 电神魔傀 II / 守护将军
魂斗罗 简体中文版
魂斗罗 简体中文版
双截龙NeoGeo
双截龙NeoGeo
《拳皇十周年纪念版》中收录的人物非常多,从疯....
《拳皇十周年纪念版》中收录的人物非常多,从疯八神到红眼怒加,各种boss级的人物都收录在其中,可以说这部作品是一直热衷于拳皇的玩家不可错过的精品。
街头霸王Ⅱ四大天王
街头霸王Ⅱ四大天王
天外魔境真传 - 东方伊甸园
天外魔境真传 - 东方伊甸园
最新街机游戏&
这个版本是众多网友改版的《口袋妖怪》,最强的....
《三国战纪:一统中原》是一款街机动作类游戏。....
SUNsoft公司制作的一款对战格斗类游戏,画面....
风云再起加强版,在原来的版本基础上加了很多....
“三国战纪-乱世枭雄”是IGS在中国国内的代理....
枪战街机-游迅小游戏合集
动作街机-游迅小游戏合集
90年代初的街机市场处于激烈的良性竞争阶段....
这是真正的科幻题材与STG相结合的完美大作!....
在一个被称为“神界的黄昏”的时代,众神均离我....
这款游戏比FC上的弹性更加加强,而且还有美女....
《A级方程式赛车》是一款赛车街机模拟游戏,在....
玩过《死亡之屋》的朋友应该还记得那种恐怖的....
拼音检索:
CopyRight2004年-年
游迅网 All Rights Reserved
备案编号:沪ICP备号-9解决N多人求小鸡模拟器运行的种种问题_小鸡模拟器吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:48,979贴子:
解决N多人求小鸡模拟器运行的种种问题
我就实在搞不懂了,你们个个用着,高端安卓,各种平板,花钱买了小鸡手柄,天天到处求二维码,求不卡设置,求存档转移,求金手指安装等等各种求,那么喜欢为什么不愿意花几百块钱买个呢,现在全新PSP也就700左右,2手的200就可以买到。可以满足你们的各种玩游戏要求,街机模拟,GBA模拟,MD模拟,模拟,PS模拟,FC模拟,大多数人玩的游戏无非就这些,天天用手机玩,你们玩的安心吗?不用担心电量吗?发热不烫手吗?
唉。。。我真是看不懂你们。
试了好几个都不行、就想...
这电脑用了有10几年了。...
WIKI抽卡模拟器,来一波...
这么的天真可爱我也不想...
缺牙要及时修复,揭秘种植牙如何做到几十年不掉?
我有啊,可是没有手机方便
我不玩模拟运行起来的游戏。。。无感。
不喜歡就別看
楼主完全不能理解便携对我们的重要意义
psp垃圾画质
psp,,3dsxl都有,但是总不能每天都带出去吧?
且不说PSP早停产了
手柄对手机有什么要求吗
Form lumia640
贴吧热议榜
使用签名档&&
保存至快速回贴1000人阅读
折腾(27)
手把手教你编写游戏模拟器 - Chip8篇
翻译整理分析:by Yiran Xie
*如要转载请附上本文链接
最近在学习游戏模拟器的编写,发现国内现成的教程少之又少,代码倒是能找到不少,不过缺乏系统的讲解看起来颇为费时费力(谁让咱是菜鸟一个呢)。于是打算一边学习,一边把搜集的资料和开发的心得整理后,陆续发布一系列关于模拟器编写的教程,本文主要讲解Chip8模拟器的编写,第二步是会发布关于编写NES(也叫FC/红白机/小霸王)模拟器编写的教程。
本文作为开篇,可能算是最容易的模拟器了,英文原文来自。我在翻译的同时添加了个人的理解作为补充,最后会分析下源代码。
Chip&8可能是所有模拟器中最容易上手的了,其中最主要的原因就是它架构比较简单。不过麻雀虽小五脏俱全,通过这样一个例子可以很好地了解模拟器的架构,为之后更复杂的模拟器编写做个铺垫。
什么是模拟器
模拟器是对于某个系统A的架构与功能的模拟,使得为系统A编写的软件可以运行在架构完全不一样的系统B上。比如原本NES游戏机(小霸王)上的游戏,现在可以通过模拟运行在PC、手持设备上等等。
什么是CHIP-8?
Chip8其实并不是个真正的系统,它更像是一个虚拟机(virtual&machine),用Chip8语言编写的游戏可以很容易地在任何装有Chip8解释器的系统中运行。它是70年代由Joseph&Weisbecker所开发。
为什么选择CHIP-8?
Chip8模拟器可能是你能发现的最容易编写的模拟器了。它仅有35个opcode(cpu指令),其中大多数都是基本的功能,在更先进的CPU架构中依然能找到。因此这样一个项目是非常具有学习价值的,可以帮你获悉CPU是如何运作的以及机器代码是如何被执行的。同时,因为它opcode数量小,所以更易管理,整个学习的曲线也更短。
在开始之前…
·&选择一门你拿手的编程语言&(常见的有C/C++&或&Java).
以下代码主要用的是&C/C++
·&这个项目不易作为学习编程的项目
·&你可能会用到第三方的库来实现音频、视频的输出以及用户的输入,比如&&/&&/&
当开始编写模拟器之前,你需要尽可能多地查找你要模拟平台上的CPU的信息。比如,它使用的内存以及寄存器的数量、大小,它用的是什么架构,要是能找到技术文档就更好了。
对于我们这里要做的Chip&8,&我建议可以参考Wiki上的。
这里先来总体介绍下Chip8的系统。
·&Chip&8&有(cpu指令),其中每个都是双字节长(2&bytes)。因此为了储存它,我们需要一种数据类型能让我们存储双字节,这里选用unsigned&short:
unsigned short
·&Chip&8共有4K内存,我们可以这么表示:
unsigned char memory[4096];
·&CPU&寄存器:Chip&8&有16个单字节(1&byte)寄存器,名字为V0,V1...到VF.&前15个寄存器为通用寄存器,最后一个寄存器(VF)是个进位标志(carry&flag).这16个寄存器表示为:
unsigned char V[16];
·&索引寄存器I(Index&register,暂译为“索引寄存器”)与&程序计数器PC(program counter),值域为0x000&到&0xFFF:
unsigned short I;
unsigned short
·&内存映像图(memory map) - 对应着上面的memory[4096]:
0x000-0x1FF - Chip 8解释器(包含用于显示的字体)
0x050-0x0A0 - 用于生成 4x5 像素的字体集合 (从’0’到’F’)
0x200-0xFFF - 游戏ROM 与工作RAM
·&图像系统:Chip&8包含一条指令用于把Sprite画到屏幕上.&这个绘画的过程用的是XOR(异或)的操作,如果一个像素经过绘画操作后被设为0(不显示),则VF寄存器被相应地更新。
·&Chip&8的显示是二值化的,总共有2048个像素&(64&x&32),每个像素有两种状态1或0(常见0表示黑,1表示白):
unsigned char gfx[64 * 32];
·&Chip&8没有中断以及硬件寄存器(hardware register,暂译为“硬件寄存器”),不过有两个timer(计时器),当它们被设定为一个正值时候,他们应当以opcode的执行频率倒计时直至0为止。(即每执行一条opcode后,如果当前两个timer为正,应当对其进行--操作。opcode的理想情况是被运行在60hz,这是需要实现者去想办法保证的)
unsigned char delay_
unsigned char sound_
·&在原系统中,当sound_timer寄存器倒计时到0时,系统会发出蜂鸣声。(这里作者写的模拟器是没有声音系统的。不过只是缺少蜂鸣声也无所谓吧)
有一点很重要,Chip&8的指令集包含了跳转(相当于jmp/goto,不用返回)或者调用子函数(相当于call,需要返回)。虽然CPU参数中并未提及栈(stack),但是你需要自己去实现一个。栈在这里被用于在调用子函数之前保存当前的pc(程序计数器)的位置,所以在任何时候你打算调用其他子函数,你需要在执行之前把当前的程序计数器push进栈,也就是所谓的“保存现场”。&这个系统用的栈有16层,同时你需要一个栈顶指针SP(stack&pointer)去指向当前的栈顶。
unsigned short stack[16];
unsigned short
最后,&Chip&8的输入是一个16个按键的键盘(0x0-0xF),&你可以用一个数组来存储当前按键的状态:
unsigned char key[16];
游戏主程序
为了提供一个更直观的感觉,&这里把游戏的的主程序做一下概述。这里不会提及如何用GLUT(OpenGL)或者SDL去实现图像或者输入系统,而仅仅是展示整个模拟器的运作过程。
//OpenGL以及输入系统的库文件
#include &chip8.h& //关于cpu核心运作的实现,一会儿会讲到
chip8 myChip8;//这里模拟器的实体mychip8被定义为全局变量
int main(int argc, char **argv)
setupGraphics();//初始化图像(窗口大小, 显示模式等等)
setupInput();//初始化输入系统
//初始化Chip8 系统以及把游戏rom加载到内存
myChip8.initialize();//清理内存、寄存器、屏幕
myChip8.loadGame(&pong&);//加载rom,“pong”是个乒乓球游戏
//模拟的主循环
  myChip8.emulateCycle();// 模拟一个指令周期
  /*由于系统不是每个周期都需要执行绘画操作,因此设立一个是否需要画图的标志位。当需要修改时把它置为1,不需要时则为0
  只有两种cpu指令(Opcode)需要设置这个标志位为1:
  0x00E0 – 清理屏幕
  0xDXYN – 把图案画到屏幕上*/
if(myChip8.drawFlag)
drawGraphics();
myChip8.setKeys();// 保存按键信息(按下与释放)
模拟器的主循环
下面我们凑近来看看。
void chip8::initialize()
//初始化内存与寄存器(注意这个操作只需执行一次)
void chip8::emulateCycle()//这个操作每个模拟周期都会执行一次
//获取opcode
//解码opcode
//执行opcode
//更新计时器
获取opcode
在这一步中,&系统会从PC(程序计数器)所指的值中取出opcode。&前面已经提到,每个opcode是双字节的,不过模拟器的内存是设置成单字节的数组(unsigned&char memory[4096]),因此我们需要一次读取连续两个字节的内容,然后把它拼接在一起去形成一个完整的opcode。
为了展示它是怎么运作的,我们这里选用opcode&0xA2F0.
// 假设如下情况
memory[pc]
memory[pc + 1] == 0xF0
为了把两个字节合并在一起,我们用如下操作:
opcode = memory[pc] && 8 | memory[pc + 1];
(如果你对位操作不是很熟悉的话,可以搜一下相关的教程看看)&
解码opcode
我们现在已经存储了当前的opcode,接着我们要去解码它,看看它究竟有什么作用。这里依然以0xA2F0为例。
经过&我们可以得知:
·&ANNN:&Sets&I&to&the&address&NNN
即把NNN这个内存地址赋给索引寄存器I(NNN 指opcode的后3位,这儿即是0x2F0。或者可以理解为A为操作指令,NNN对应着操作数)。
执行opcode
现在我们已经明确了我们要对opcode执行什么操作,因此我们可以在模拟器中模拟这个操作。比如还是&0xA2F0这条指令,我们现在把0x2F0赋给索引寄存器I:0xA2F0是16位的,我们要从中取出低12位的0x2F0,这里通过与掩码进行'&'操作实现:
I = opcode & 0x0FFF;
pc += 2;
因为每条指令都是双字节长,所以我们需要把程序计数器的步进长度设为2,即一次前进2个字节。除非这条opcode是跳转,则需要更改PC,前面也讲过了,在调用子函数之前,则还需要把PC压入栈。在一些指令下,下一条opcode可能需要被跳过(有些opcode的作用为“当满足xxx情况时,跳过下条指令”),显然此时程序计数器一次前进4个字节.
除了执行opcode以外,Chip&8&还有两个计时器delay timer和sound timer需要去实现。就像前面提及的,在每一个主循环内两个计时器应当分别--,直至0。
原系统是以60hz的速度运行,即每秒执行60条op code,对于我们来说,就是每秒执行60个main loop。而由于现代CPU的高效,如果我们不去显式控制执行周期的话,在全速运行的时候显然会远远超过60hz,这样的结果就是游戏节奏过快,没有可玩性了。因此可以想象到我们需要实现一个自己的计时器,在每个循环内把剩余的时间消耗掉,使得执行速率尽可能地稳定在60hz。
现在你应该已经知道了模拟的基本过程以及整个系统是怎么运作的,那么现在就把各部分合并开始编写这个模拟器吧!
初始化系统
在执行第一个模拟周期之前,你需要做一些准备工作:初始化内存以及寄存器。虽然Chip8没有BIOS或系统固件,它却有一个基本的字体集(数字和字母的显示字体集合)存在内存中。字体集的大小为0x50,应当被存入到内存中0x00-0x50的地方。
另一个需要注意的是游戏ROM(相当于代码段)应当被加载到0x200的地方,那么pc最初也应该指向这里。
void chip8::initialize()
//程序计数器指向 0x200
opcode = 0;
//初始化“当前opcode”
//初始化索引寄存器
//初始化栈顶指针
//清理显存
//清理从V0到VF的寄存器
//清理内存
// 读取字体集
for(int i = 0; i & 80; ++i)
memory[i] = chip8_fontset[i];
//初始化计时器
把程序(游戏ROM)读入内存
在初始化之后,把程序读入内存(用fopen以二进制方式打开)并且把内容依次读取到0x200(512)开始的内存中:
for(int i = 0; i & bufferS ++i)
memory[i + 512] = buffer[i];
现在我们的系统已经准备好去执行它的第一条指令。就像之前提到的,我们需要按照获取/解码/执行的步骤执行opcode。在这个例子中,我们首先读取opcode的高4位,然后看看这个opcode的作用:
void chip8::emulateCycle()
//获取opcode
opcode = memory[pc] && 8 | memory[pc + 1];
//解码opcode(这里先读取高4位用于判断)
switch(opcode & 0xF000)
//...其他opcodes
case 0xA000: //ANNN:把NNN赋给索引寄存器I
//执行opcode
I = opcode & 0x0FFF;
pc += 2;
//...其他opcodes
printf (&Unknown opcode: 0x%X\n&, opcode);
//更新timers(opcode与timer频率相同)
if(delay_timer & 0)
if(sound_timer & 0)
if(sound_timer == 1)
printf(&BEEP!\n&);//好吧,有点雷-.-
不过在一些情况下,我们不能仅凭借前4位去判断这条opcode的作用。在这种情况下,我们需要进一步去判断其低4位。
//解码opcode
switch(opcode & 0xF000)//这是判断高4位
case 0x0000://当高4位都是0时,需要进一步判断其低4位
switch(opcode & 0x000F)//进一步判断低4位
case 0x0000: // 0x00E0:清理屏幕
//执行“清理屏幕”
case 0x000E: // 0x00EE:从子函数返回
//执行“从子函数返回”
printf (&Unknown opcode [0x0000]: 0x%X\n&, opcode);
//更多的opcodes //
Opcode中一些需要注意的特例
例1:&Opcode&0x2NNN (call NNN)
这条opcode调用位于NNN地址的子函数,在跳转之前我们把当前PC中的地址进行保存,以便子函数结束后能够返回。在储存完毕之后,栈顶指针应当指向下一个空位(注意,这个栈是向上生长的,所以是++)。接着,把PC设为新的地址(通过与0x0FFF进行与操作取得“NNN”对应的地址)。
case 0x2000:
stack[sp] =
++
pc = opcode & 0x0FFF;
例2:&Opcode&0x8XY4
这条指令把寄存器VY累加到VX上,比如0x8534,即X=5,Y=3,则意味着运算V5 + V3.如果加法过程中出现了溢出,则要把寄存器VF(前面提到的16个寄存器中的最后一个,进位寄存器)相应置为1,如果没有溢出,则置为0。因为寄存器是单字节的,仅能存储0~255,当VX与VY之和大于255时,它就不能被完整地存于寄存器中(超出255的部分会从0重新开始累加),所以我们用VF这个寄存器来告知系统VX,VY之和实际上&255。&别忘了执行的最后要把PC + 2.
case 0x0004:
if(V[(opcode & 0x00F0) && 4] & (0xFF - V[(opcode & 0x0F00) && 8]))//即VY & 255 - VX
V[0xF] = 1;//出现了溢出,则把VF置为1
V[0xF] = 0;//没有溢出VF置为0
V[(opcode & 0x0F00) && 8] += V[(opcode & 0x00F0) && 4];//VX += VY
pc += 2;
例3:&Opcode&0xFX33
作用:把VX的十进制的表示存于I/I+1/I+2三个地址。其中I存百位,I+1存十位,I+2存个位。
case 0x0033:
= V[(opcode & 0x0F00) && 8] / 100;//取得十进制百位
memory[I + 1] = (V[(opcode & 0x0F00) && 8] / 10) % 10;//取得十进制十位
memory[I + 2] = (V[(opcode & 0x0F00) && 8] % 100) % 10;//取得十进制个位
pc += 2;
处理图像与输入
像素的绘制
负责处理图像输出的opcode是0xDXYN。
表示在(VX,&VY)坐标处画一个像素宽度固定为8,像素高度为N的sprite(小图案)。这个图案在内存中的起始地址存于索引寄存器I中。每个字节的8位刚好表示8个像素,1个像素对应1位,类似bitmap,第一个字节中保存着图案第一行的8个像素,第二个字节中保存着图案第二行的8个像素,以此类推。
假设当前的opcode为0xD003,则说明想在(V[0], V[0])处画一个宽为8,高为3的图案。一个例子
memory[I + 1] = 0xC3;
memory[I + 2] = 0xFF;//这些值只是个例子
以上这3个字节是如何表达一个图案的?看看他们的二进制表示吧,这样更直观:
是不是很有趣呢?
另外,还有个概念叫“碰撞”。在通过异或来设置gfx[]之前,如果某像素p当前处于“点亮”的状态(即显示缓存gfx[p]为1),同时这次绘画依然希望它为1,则称为发生了“碰撞”,此时把VF置为1,否则置为0.
最后要说的是gfx中的存储结构,gfx比较慷慨,不再用一位而是用一个字节来表示一个像素,其值为0或1。它的横向分辨率为64个像素.因此(x,y)在gfx中的地址应该为gfx[64 * y + x]。
opcode&0xDXYN的实现范例:
//绘画指令
case 0xD000:
unsigned short x = V[(opcode & 0x0F00) && 8];
unsigned short y = V[(opcode & 0x00F0) && 4];//取得x,y(横纵坐标)
unsigned short height = opcode & 0x000F;//取得N(图案的高度)
unsigned short
V[0xF] = 0;//初始化VF为0
for(int yline = 0; yline & yline++)//对于每一行
pixel = memory[I + yline];//取得内存I处的值,pixel中包含了一行的8个像素
for(int xline = 0; xline & 8; xline++)//对于一行的8个像素
if(pixel & (0x80 && xline))//依次检查新值中每一位是否为1
if(gfx[(x + xline + ((y + yline) * 64))])//如果显示缓存gfx[]里该像素也为1,则发生了碰撞
V[0xF] = 1;//设置VF为1
gfx[x + xline + ((y + yline) * 64)] ^= 1;//gfx中用1个byte来表示1个像素,其值为0或1。这个异或相当于取反
drawFlag = true;//绘画标志位置为1,通知外层循环我们有东西要画啦
pc += 2;
Chip&8系统用了16个按键的键盘来接受输入。对于我们的模拟器来说,需要实现一个方法用于记录所有键的状态。在每次的执行周期中,都需要查看按键的状态,并且把它更新到key[].当按键被按下后,我们把key[]中对应位置为1,当按键被释放(抬起)后,把它置为0。opcode&0xEX9E和0xEXA1会去检查某个指定的按键是否被按下或释放,opcode&0xFX0A会等待一个按键被按下,一旦当它接收到,它会把被按下的按键的序号而不是按键的状态存入寄存器。
case 0xE000:
switch(opcode & 0x00FF)
// EX9E: 如果VX中保存的按键此时被按下,则跳过下条指令
case 0x009E:
if(key[V[(opcode & 0x0F00) && 8]])
pc += 4;
pc += 2;
下图左边是原始键盘的按键分布。事实上怎么映射按键可以随你个人兴趣,不过建议你设置成下图右边的方式。
+-+-+-+-+
+-+-+-+-+
+-+-+-+-+
+-+-+-+-+
+-+-+-+-+
+-+-+-+-+
+-+-+-+-+
+-+-+-+-+
+-+-+-+-+
+-+-+-+-+
CHIP-8字体集
这是Chip&8的字体集。每个字符用一个像素矩阵来表示,4像素宽(即每个字节的高4位),5像素高。
unsigned char chip8_fontset[80] =
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
0x20, 0x60, 0x20, 0x20, 0x70, // 1
0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
0x90, 0x90, 0xF0, 0x10, 0x10, // 4
0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
0xF0, 0x10, 0x20, 0x40, 0x40, // 7
0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
0xF0, 0x90, 0xF0, 0x90, 0x90, // A
0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
0xE0, 0x90, 0x90, 0x90, 0xE0, // D
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
0xF0, 0x80, 0xF0, 0x80, 0x80
上面看起来有点杂乱无章,不过来看看其二进制表示:
10进制 16进制
10进制 16进制
希望这个教程能为你自己DIY模拟器提供足够多的信息。至少你应该有了一个模拟器如何运作以及CPU如何执行指令的基本的概念。
作者在最后提供了三个版本的源代码,一个新版本,一个旧版本,一个Android的版本。这里主要讨论下其,其余版本可以在末尾处找到。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:138312次
积分:2542
积分:2542
排名:第11836名
原创:112篇
转载:29篇
评论:35条
(1)(3)(3)(2)(1)(1)(1)(2)(5)(1)(4)(4)(1)(1)(1)(2)(5)(1)(2)(4)(3)(8)(2)(2)(3)(2)(1)(1)(1)(1)(1)(2)(5)(2)(6)(5)(5)(2)(1)(10)(7)(1)(1)(2)(3)(3)(7)(1)(4)(3)(2)

我要回帖

更多关于 n3dsll街机模拟器cps 的文章

 

随机推荐