Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
实现CPU指令的仿真?_C_Emulation - Fatal编程技术网

实现CPU指令的仿真?

实现CPU指令的仿真?,c,emulation,C,Emulation,我正在努力学习仿真编程。我用40条指令做了一个芯片8模拟器,因为我的音乐而活了下来。我现在希望做一些更复杂的事情,比如SNES。我遇到的问题是CPU指令的数量太多了。从后面看,这就像是后部的疼痛。我在不同的网页上看到过这样或那样的注释,CPU是模拟器中最容易实现的部分 假设这很难,因为我做错了,我环顾四周,发现了一个简单的实现:大约900行代码。很容易完成 然后,从源代码中,我找到了CPU指令的位置。看起来比我想的简单多了。我真的不明白,但这只是几行代码,而不是大量的代码。我注意到的第一件事是每

我正在努力学习仿真编程。我用40条指令做了一个芯片8模拟器,因为我的音乐而活了下来。我现在希望做一些更复杂的事情,比如SNES。我遇到的问题是CPU指令的数量太多了。从后面看,这就像是后部的疼痛。我在不同的网页上看到过这样或那样的注释,CPU是模拟器中最容易实现的部分

假设这很难,因为我做错了,我环顾四周,发现了一个简单的实现:大约900行代码。很容易完成

然后,从源代码中,我找到了CPU指令的位置。看起来比我想的简单多了。我真的不明白,但这只是几行代码,而不是大量的代码。我注意到的第一件事是每个指令只有一个实现。如果你看这张桌子,你会发现它有

ADC #const
ADC (_db_),X
ADC (_db_,X)
ADC addr
ADC long
...
(我认为)所有这些的模拟器源代码是:

// Note: op 0x100 means "NMI", 0x101 means "Reset", 0x102 means "IRQ". They are implemented in terms of "BRK".
// User is responsible for ensuring that WB() will not store into memory while Reset is being processed.
unsigned addr=0, d=0, t=0xFF, c=0, sb=0, pbits = op<0x100 ? 0x30 : 0x20;

// Define the opcode decoding matrix, which decides which micro-operations constitute
// any particular opcode. (Note: The PLA of 6502 works on a slightly different principle.)
const unsigned o8 = op / 32, o8m = 1u << (op%32);
// Fetch op'th item from a bitstring encoded in a data-specific variant of base64,
// where each character transmits 8 bits of information rather than 6.
// This peculiar encoding was chosen to reduce the source code size.
// Enum temporaries are used in order to ensure compile-time evaluation.
#define t(w8,w7,w6,w5,w4,w3,w2,w1,w0) if( \
        (o8<1?w0##u : o8<2?w1##u  : o8<3?w2##u : o8<4?w3##u : \
         o8<5?w4##u : o8<6?w5##u  : o8<7?w6##u : o8<8?w7##u : w8##u) & o8m)

t(0,0xAAAAAAAA,0x00000000,0x00000000,0x00000000,0xAAAAA2AA,0x00000000,0x00000000,0x00000000) { c = t; t += A + P.C; P.V = (c^t) & (A^t) & 0x80; P.C = t & 0x100; }
//注意:op 0x100表示“NMI”,0x101表示“重置”,0x102表示“IRQ”。它们是根据“BRK”实现的。
//用户负责确保在处理重置时WB()不会存储到内存中。

无符号addr=0,d=0,t=0xFF,c=0,sb=0,pbits=op我不能回答所有这些问题,但是
dp
代表直接页,这意味着指令采用单字节操作数,它是直接页中的内存地址。直接页寻址是6502零页寻址模式的扩展,其中单字节地址指的是内存位置
$00
$FF
。6502的16位衍生物有一个配置寄存器,基本上将零页重新定位到另一个位置。f

在您链接到的wiki页面中,表中的一些
dp
上有下划线,其他的是斜体。我假设它们都是斜体的,并且wiki标记不起作用。对编辑链接的快速检查支持这种假设(在wiki源代码中,它们都有下划线)。所以不要读任何东西

在6502组件及其衍生产品中,
ADC-dp,X
表示。。。让我们举出一个具体的例子来代替…code>ADC$10,X
表示将
$10
添加到寄存器
X
中的值以获得地址,然后从该地址加载一个值并将其添加到累加器中
ADC($10,X)
添加了额外的间接寻址级别:将
$10
添加到
X
以获取地址,从该地址加载值,将加载值解释为另一个地址,然后从该地址加载值并将其添加到累加器。括号内的操作数总是添加一级间接寻址

请注意,可用模式包括
(dp,X)
(dp),Y
,括号相对于逗号和寄存器的位置非常重要。使用
(dp),Y
Y
的值添加到第一次加载的值中,以获得在第二次加载中使用的地址

至于那个模拟器。。。代码高尔夫不会提高可读性!我不认为你发布的那部分内容本身是可以理解的,我也不想追踪和阅读它的其余部分。但是
t
宏中的关键概念是位字符串。它的参数是一系列9位掩码,每个32位长,总共288位。因此,每个可能的操作码(256个),加上第一条注释中提到的3个伪操作码,都由这个288位长的位字符串中的一个位表示,剩余29位

这就解释了
o8
o8m
的构造。8位值分为3位部分(从提供给
t
的8个参数中选择一个参数)和5位部分(从所选参数中选择一个位)。大的
?:
链执行第一个选择以及
&
1的组合
0,          # opcodes $100 and up
0xAAAAAAAA, # opcodes $E0 to $FF
0x00000000, # opcodes $C0 to $DF
0x00000000, # opcodes $A0 to $BF
0x00000000, # opcodes $80 to $9F
0xAAAAA2AA, # opcodes $60 to $7F
0x00000000, # opcodes $40 to $5F
0x00000000, # opcodes $20 to $3F
0x00000000  # opcodes $00 to $1F
0,                                  # opcodes $100 and up
0b10101010101010101010101010101010, # opcodes $E0 to $FF
0b00000000000000000000000000000000, # opcodes $C0 to $DF
0b00000000000000000000000000000000, # opcodes $A0 to $BF
0b00000000000000000000000000000000, # opcodes $80 to $9F
0x10101010101010101010001010101010, # opcodes $60 to $7F
0b00000000000000000000000000000000, # opcodes $40 to $5F
0b00000000000000000000000000000000, # opcodes $20 to $3F
0b00000000000000000000000000000000  # opcodes $00 to $1F