文档章节

VM技术(二)从CHIP8入手CPU的模拟(二)

Pulsar-V
 Pulsar-V
发布于 07/31 15:54
字数 1341
阅读 2
收藏 0

CHIP指令表

CHIP-8有35个指令,都为两字节长,以大端方式存储。指令表的指令格式规定如下:

NNN 地址
NN 8位常量
N 4位常量
V 寄存器
X和Y 4位,标识寄存器
PC 程序计数器
I 16位索引地址寄存器
序号 操作码 类型 功能描述
1 0NNN 调用 执行地址NNN的子程序
2 00E0 显示 清屏
3 00EE 跳转 从子程序返回
4 1NNN 跳转 跳转到地址NNN
5 2NNN 跳转 调用子程序NNN
6 3XNN 条件 如果VX等于NN则跳过下一条指令(通常时跳过一条跳转指令)
7 4XNN 条件 如果VX不等于NN则跳过下一条指令(同上)
8 5XY0 条件 如果VX的值等于VY则跳过下一条指令(同上)
9 6XNN 赋值 VX = NN
10 7XNN 赋值 VX += NN,进位标记不会改变
11 8XY0 赋值 VX = VY
12 8XY1 按位或 VX = VX
13 8XY2 按位与 VX = VX & VY
14 8XY3 按位异或 VX = VX ^ VY
15 8XY4 运算 VX += VY,VX有进位(大于255)时VF为1,否则VF为0
16 8XY5 运算 VX -= VY,VX负数时VF为0,否则VF为1
17 8XY6 右移 VX >>= 1,VX最低位存入VF中
18 8XY7 运算 VX = VY - VX,VX负数时VF为0,否则VF为1
19 8XYE 左移 VX <<= 1,VX最高位存入VF中
20 9XY0 条件 如果VX不等于VY则跳过下一条指令(通常时跳过一条跳转指令)
21 ANNN 地址 将I设置为NNN
22 BNNN 跳转 跳转到地址V0+NNN,PC=V0+NNN
23 CXNN 随机数 VX = rand() & NN
24 DXYN 显示 在(VX,VY)绘制一个宽8像素、高N像素的精灵。每8个像素从I寄存器中的地址逐步读出一字节(8位),在执行该语句时I内的值不可以改变,如果像素反转为0则碰撞检测将VF置为1
25 EX9E 按键 跳过下一条指令,如果存储在VX的键值所应的键被按下
26 EXA1 按键 跳过下一条指令,如果存储在VX的键值所应的键没有被按下
27 FX07 定时器 获取延时寄存器的值
28 FX0A 按键 等待按键,将按键的值存入VX(阻塞指令,所有指令将等待该指令执行完
29 FX15 定时器 将VX的值存入延时寄存器
30 FX18 定时器 将VX的值存入声音寄存器
31 FX1E 地址 I += VX
32 FX29 地址 将VX中的精灵地址赋值给I,字符0-F由4X5字体表示
33 FX33 BCD 将VX中值的BCD码存入I中的地址内,百位在I,十位在I+1,个位在I+2
34 FX55 地址 将V0到VX的值存入I中地址为起始的内存空间
35 FX65 地址 将I中地址为起始的内容依次存入V0-VX

对每一个OPcode的实现

0NNN

//no action

00E0

    memset(gfx, 0, sizeof(gfx));
    drawFlag = true;
    pc += 2;

00EE

    pc = stack[--sp] + 2;

1NNN

    pc = opcode & 0x0FFF;

2NNN

    stack[sp++] = pc;
    pc = opcode & 0x0FFF;

3XNN

    pc += (V[(opcode & 0x0F00) >> 8] == (opcode & 0x00FF)) ? 4 : 2;

4XNN

    pc += (V[(opcode & 0x0F00) >> 8] != (opcode & 0x00FF)) ? 4 : 2;

5XY0

    pc += (V[(opcode & 0x0F00) >> 8] == V[(opcode & 0x00F0) >> 4]) ? 4 : 2;

6XNN

    V[(opcode & 0x0F00) >> 8] = opcode & 0x00FF;
    pc += 2;

7XNN

    V[(opcode & 0x0F00) >> 8] += opcode & 0x00FF;
    pc += 2;

8XY0

    V[(opcode & 0x0F00) >> 8] = V[(opcode & 0x00F0) >> 4];
    pc += 2;

8XY1

    V[(opcode & 0x0F00) >> 8] |  = V[(opcode & 0x00F0) >> 4];
    pc += 2;

8XY2

    V[(opcode & 0x0F00) >> 8] &= V[(opcode & 0x00F0) >> 4];
    pc += 2;

8XY3

    V[(opcode & 0x0F00) >> 8] ^= V[(opcode & 0x00F0) >> 4];
    pc += 2;

8XY4

    V[0xF] = V[(opcode & 0x00F0) >> 4] > (0xFF - V[(opcode &0x0F00) >> 8]);
    V[(opcode & 0x0F00) >> 8] += V[(opcode & 0x00F0) >> 4];
    pc += 2;

8XY5

    V[0xF] = !(V[(opcode & 0x00F0) >> 4] > V[(opcode & 0x0F00) >> 8]);
    V[(opcode & 0x0F00) >> 8] -= V[(opcode & 0x00F0) >> 4];
    pc += 2;

8XY6

    V[0xF] = V[(opcode & 0x0F00) >> 8] & 0x1;
    V[(opcode & 0x0F00) >> 8] >>= 1;
    pc += 2;

8XY7

    V[0xF] = !(V[(opcode & 0x0F00) >> 8] > V[(opcode & 0x00F0) >> 4]);
    V[(opcode & 0x0F00) >> 8] = V[(opcode & 0x00F0) >> 4] - V[(opcode & 0x0F00) >> 8];
    pc += 2;

8XYE

    V[0xF] = V[(opcode & 0x0F00) >> 8] >> 7;
    V[(opcode & 0x0F00) >> 8] <<= 1;
    pc += 2;

9XY0

    pc += (V[(opcode & 0x0F00) >> 8] != V[(opcode & 0x00F0) >> 4]) ? 4 : 2;

ANNN

    I = opcode & 0x0FFF;
    pc += 2;

BNNN

    pc = (opcode & 0x0FFF) + V[0];

CXNN

    V[(opcode & 0x0F00) >> 8] = (rand   % 0xFF) & (opcode & 0x00FF);
    pc += 2;

DXYN

    unsigned short x = V[(opcode & 0x0F00) >> 8];
    unsigned short y = V[(opcode & 0x00F0) >> 4];
    unsigned short height = opcode & 0x000F;
    unsigned short pixel = 0;
    V[0xF] = 0;
    for(int yline = 0; yline < height; ++yline) {
        pixel = memory[I+yline];
        for(int xline = 0; xline < 8; ++xline) {
            if((pixel & (0x80 >> xline)) != 0)
            {
                if(gfx[(x + xline + ((y + yline) * 64))] == 1)
                {
                    V[0xF] = 1;
                }
                gfx[x + xline + ((y + yline) * 64)] ^= 1;
            }
        }
    }
    drawFlag = true;
    pc += 2;

EX9E

    pc += (key[V[(opcode & 0x0F00) >> 8]]) ? 4 : 2;

EXA1

    pc += (key[V[(opcode & 0x0F00) >> 8]]) ? 2 : 4;

FX07

    V[(opcode & 0x0F00) >> 8] = delay_timer;
    pc += 2;

FX0A

    bool keyPress = false;

    for(int i = 0; i < 16; ++i)
    {
        if(key[i] != 0)
        {
            V[(opcode & 0x0F00) >> 8] = i;
            keyPress = true;
        }
    }

    if(!keyPress) {
        return;
    }
    pc += 2;

FX15

    delay_timer = V[(opcode & 0x0F00) >> 8];
    pc += 2;

FX18

    sound_timer = V[(opcode & 0x0F00) >> 8];
    pc += 2;

FX1E

    V[0xF] = (I + V[(opcode & 0x0F00) >> 8]) > 0xFFF;
    I += V[(opcode & 0x0F00) >> 8];
    pc += 2;

FX29

    I = V[(opcode & 0x0F00) >> 8] * 5;
    pc += 2;

FX33

    unsigned short vx = V[(opcode & 0x0F00) >> 8];
    memory[I] = vx / 100;
    memory[I+1] = vx / 10 % 10;
    memory[I+2] = vx % 10;
    pc += 2;

FX55

    unsigned short vx = V[(opcode & 0x0F00) >> 8];
    for(int i = 0; i <= vx; ++i) {
        memory[I+i] = V[i];
    }
    I += ((opcode & 0x0F00) >> 8) + 1;
    pc += 2;

FX65

    unsigned short vx = V[(opcode & 0x0F00) >> 8];
    for(int i = 0; i <= vx; ++i) {
        V[i] = memory[I+i];
    }
    I += ((opcode & 0x0F00) >> 8) + 1;
    pc += 2;

© 著作权归作者所有

Pulsar-V

Pulsar-V

粉丝 61
博文 151
码字总数 135961
作品 1
成都
架构师
私信 提问
VM技术(二)从CHIP8入手CPU的模拟(一)

CHIP8的话网上已经有许多的模拟器的解说了,这里我们就给出CPU的模拟过程 CHIP8代码 CHIP8 CPU https://gitee.com/Luciferearth/EasyVGM/blob/master/modules/CHIP8/显示器 https://gitee.co...

Pulsar-V
07/31
22
0
初识openstack之1——虚拟化介绍及KVM虚拟机

一、基础知识 CPU的工作机制 随着云计算的兴起,虚拟化作为云计算的组成部分也火了一把,但虚拟化并不是什么新技术,早在上世纪70年代虚拟化技术就已经出现。传统的CPU由4个环组成,分为:环...

qiao645
2018/06/29
0
0
虚拟化技术

虚拟化技术 虚拟化技术: 计算机基本部件:控制器+运算器=CPU memory I/O(keyboard monitor) 虚拟化:将底层的计算机资源抽象或者虚拟为多组彼此之间互相隔离的计算平台,每一个平台都具有...

Taxing祥
2017/08/19
0
0
redhat6.5下安装配置kvm虚拟机

-------------------------- 一、前言 二、环境 三、安装与配置 四、创建kvm虚拟机 五、管理kvm虚拟机 六、克隆kvm虚拟机 七、网络配置(bridge) 附1:宿主机执行以下指令(shutdown,reboot)虚...

_诺千金
2014/10/13
0
0
『中级篇』容器的技术概述(二)

容器的前世今生 ###物理机 部署非常慢 购买服务器服务,放在IDC机房,各种走流程,很多流程不可控制流程慢。 成本非常高 物理的服务器,高额的配置成本贵。 资源浪费 资源太多了,针对app的服...

IT人故事
2018/07/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

重新开始学Java——反射

概念 reflection:自省 反射:镜子可以反射阳光一个java类 或 对象 通过照"镜子"来认知自己 Java语言中是怎么实现照镜子? java.lang.reflect 包 提供了"照镜子"API(应用程序接口) 如果要...

大家都是低调来的
7分钟前
1
0
爬取720万条城市历史天气数据

内容爬虫完毕,校验完毕,缺失信息暂未统计。总数据720万,地区3200个,年份从2011-2019,大小950Mb,原始数据已丢失,需要的朋友可以自己运行脚本挂一晚上。中间遇到了很多坑,有机会我再写...

八音弦
11分钟前
4
0
python的字典类型

1、新建字典 通过键值对 dict_1 = {'a':1,'b':2,'c':3} 通过dict()函数 list_1 = ['adam', 'bob', 'cathy', 'david', 'emma'] list_2 = [1,2,3,4,5] dict_2 = dict(zip(list_1,list_2)) 2、字......

davidwbnu
13分钟前
1
0
springcloud vue.js 前后分离 activiti工作流

本商品为 :springcloud + Springboot 微服务\分布式 工作流 前后分离 + 跨域 版本 (权限控制到菜单和按钮) 后台框架 :springcloud Greenwich.SR1 + springboot 2.1.4 + activiti6.0.0 + ...

java框架开发者
19分钟前
6
0
【jQuery基础学习】07 jQuery表单插件-Form

本文转载于:专业的前端网站➦【jQuery基础学习】07 jQuery表单插件-Form 作用:jQuery Form插件的作用是为了让我们可以很方便地用ajax的方式提交表单,从而使我们提交表单的时候页面不用进行...

前端老手
28分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部