NES模拟器开发 - 资料归纳整理 - 指令集篇
-by Yiran Xie
*转载请附上本文链接
在这篇中主要对于编写模拟器需要了解的6502的CPU的指令集(instruction set)进行介绍。参考了很多资料,做了汇总、整理和翻译,对于其中一些语义不详的,补充了个人理解。在阅读本篇以前,应当先阅读<资料归纳整理之CPU篇>。
标记方法:
A 累加寄存器
X, Y X,Y寄存器
P 状态寄存器(status register)
SP 栈顶指针寄存器
PC 程序计数器
PCH 程序计数器高字节
PCL 程序计数器低字节
M 内存
OPER 操作数
# 立即数
/ 该标志位发生了变化
_ 该标志位未发生变化
+ 加
- 减
AND 逻辑与
OR 逻辑或
XOR 逻辑异或
POP 出栈
PUSH 入栈
-> transfer to
<- transfer from
6502指令集 - 按字母顺序排列:
1. ADC Add memory to accumulator with carry 将内存中的值与A求和,存于A,有进位C参与其中 Operation: A + M + C -> A, C
+----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | ADC #Oper | 69 | 2 | 2 | | Zero Page | ADC Oper | 65 | 2 | 3 | | Zero Page,X | ADC Oper,X | 75 | 2 | 4 | | Absolute | ADC Oper | 6D | 3 | 4 | | Absolute,X | ADC Oper,X | 7D | 3 | 4* | | Absolute,Y | ADC Oper,Y | 79 | 3 | 4* | | (Indirect,X) | ADC (Oper,X) | 61 | 2 | 6 | | (Indirect),Y | ADC (Oper),Y | 71 | 2 | 5* | +----------------+-----------------------+---------+---------+----------+
* 当操作跨内存页(page)的时候加1
对标志位的影响:
C | Carry Flag | Set if overflow in bit 7 |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Set if sign bit is incorrect |
N | Negative Flag | Set if bit 7 set |
2. AND "AND" memory with accumulator 将内存与A进行逻辑与,存于A Operation: A AND M -> A +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | AND #Oper | 29 | 2 | 2 | | Zero Page | AND Oper | 25 | 2 | 3 | | Zero Page,X | AND Oper,X | 35 | 2 | 4 | | Absolute | AND Oper | 2D | 3 | 4 | | Absolute,X | AND Oper,X | 3D | 3 | 4* | | Absolute,Y | AND Oper,Y | 39 | 3 | 4* | | (Indirect,X) | AND (Oper,X) | 21 | 2 | 6 | | (Indirect,Y) | AND (Oper),Y | 31 | 2 | 5 | +----------------+-----------------------+---------+---------+----------+ * 当操作跨内存页(page)的时候加1
C | Carry Flag | Not affected |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 set |
3.ASL ASL Shift Left One Bit (Memory or Accumulator) 将内存中或A中的值左移1位 +-+-+-+-+-+-+-+-+ Operation: C <- |7|6|5|4|3|2|1|0| <- 0 +-+-+-+-+-+-+-+-+ +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Accumulator | ASL A | 0A | 1 | 2 | | Zero Page | ASL Oper | 06 | 2 | 5 | | Zero Page,X | ASL Oper,X | 16 | 2 | 6 | | Absolute | ASL Oper | 0E | 3 | 6 | | Absolute, X | ASL Oper,X | 1E | 3 | 7 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set to contents of old bit 7 |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of the result is set |
4. BCC BCC Branch on Carry Clear 判断C(进位标志)是否为0进行跳转 Operation: Branch on C = 0 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Relative | BCC Oper | 90 | 2 | 2* | +----------------+-----------------------+---------+---------+----------+ * 如果目的地址位于同一个内存页,则加1 * 如果位于不同页,则加2
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
5. BCS BCS Branch on carry set 判断C是否为1进行跳转 Operation: Branch on C = 1 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Relative | BCS Oper | B0 | 2 | 2* | +----------------+-----------------------+---------+---------+----------+ * 如果目的地址位于同一个内存页,则加1 * 如果位于不同页,则加2
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
6. BEQ BEQ Branch on result zero 判断Z(zero标志位)是否为1进行跳转 Operation: Branch on Z = 1 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Relative | BEQ Oper | F0 | 2 | 2* | +----------------+-----------------------+---------+---------+----------+
* 如果目的地址位于同一个内存页,则加1
* 如果位于不同页,则加2
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
7. BIT BIT Test bits in memory with accumulator 内存M与A进行逻辑与,然后把M的Bit 6和Bit 7给P中的V与N标志位。 Operation: A AND M, M6 -> V, M7 -> N +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Zero Page | BIT Oper | 24 | 2 | 3 | | Absolute | BIT Oper | 2C | 3 | 4 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if the result if the AND is zero |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Set to bit 6 of the memory value |
N | Negative Flag | Set to bit 7 of the memory value |
8. BMI BMI Branch on result minus 判断N标志位(符号标志位)是否为1进行跳转 Operation: Branch on N = 1 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Relative | BMI Oper | 30 | 2 | 2* | +----------------+-----------------------+---------+---------+----------+
* 如果目的地址位于同一个内存页,则加1
* 如果位于不同页,则加2
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
9. BNE BNE Branch on result not zero 判断Z标志位是否为0进行跳转 Operation: Branch on Z = 0 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Relative | BMI Oper | D0 | 2 | 2* | +----------------+-----------------------+---------+---------+----------+ * 如果目的地址位于同一个内存页,则加1
* 如果位于不同页,则加2
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
10. BPL BPL Branch on result plus 判断N标志位是否为0进行跳转 Operation: Branch on N = 0 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Relative | BPL Oper | 10 | 2 | 2* | +----------------+-----------------------+---------+---------+----------+ * 如果目的地址位于同一个内存页,则加1
* 如果位于不同页,则加2
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
11. BRK BRK Force Break 产生软中断(对于PC+2和P进行压栈,然后把$FFFE/$FFFF写入PC) Operation: Forced Interrupt, PUSH PC + 2, PUSH P +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | BRK | 00 | 1 | 7 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Set to 1 |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
12. BVC BVC Branch on overflow clear 判断V(溢出标志)是否为0进行跳转 Operation: Branch on V = 0 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Relative | BVC Oper | 50 | 2 | 2* | +----------------+-----------------------+---------+---------+----------+ * 如果目的地址位于同一个内存页,则加1
* 如果位于不同页,则加2
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
13. BVS BVS Branch on overflow set 判断V是否为1进行跳转 Operation: Branch on V = 1 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Relative | BVS Oper | 70 | 2 | 2* | +----------------+-----------------------+---------+---------+----------+
* 如果目的地址位于同一个内存页,则加1
* 如果位于不同页,则加2
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
14. CLC CLC Clear carry flag 清除C标志位 Operation: C = 0 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | CLC | 18 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set to 0 |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
15. CLD CLD Clear decimal mode 清除D标志位(十进制表示标志) Operation: D = 0 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | CLD | D8 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Set to 0 |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
注意:机器刚启动时或者reset后,D标志位的状态是不确定的,因此应当将其清0再使用
16. CLI CLI Clear interrupt disable bit 清除I标志位(中断禁止标志) Operation: I = 0 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | CLI | 58 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Set to 0 |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
17. CLV CLV Clear overflow flag 清除V标志位(溢出标志位) Operation: V = 0 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | CLV | B8 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Set to 0 |
N | Negative Flag | Not affected |
18. CMP CMP Compare memory and accumulator 比较内存与A(A-M) Operation: A - M +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | CMP #Oper | C9 | 2 | 2 | | Zero Page | CMP Oper | C5 | 2 | 3 | | Zero Page,X | CMP Oper,X | D5 | 2 | 4 | | Absolute | CMP Oper | CD | 3 | 4 | | Absolute,X | CMP Oper,X | DD | 3 | 4* | | Absolute,Y | CMP Oper,Y | D9 | 3 | 4* | | (Indirect,X) | CMP (Oper,X) | C1 | 2 | 6 | | (Indirect),Y | CMP (Oper),Y | D1 | 2 | 5* | +----------------+-----------------------+---------+---------+----------+ * 当操作跨内存页(page)的时候加1
C | Carry Flag | Set if A >= M |
Z | Zero Flag | Set if A = M |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of the result is set |
19. CPX CPX Compare Memory and Index X 比较内存与X(X - M) Operation: X - M +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | CPX *Oper | E0 | 2 | 2 | | Zero Page | CPX Oper | E4 | 2 | 3 | | Absolute | CPX Oper | EC | 3 | 4 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set if X >= M |
Z | Zero Flag | Set if X = M |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of the result is set |
20. CPY CPY Compare memory and index Y 比较内存与Y(Y - M) Operation: Y - M +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | CPY *Oper | C0 | 2 | 2 | | Zero Page | CPY Oper | C4 | 2 | 3 | | Absolute | CPY Oper | CC | 3 | 4 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set if Y >= M |
Z | Zero Flag | Set if Y = M |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of the result is set |
21. DEC DEC Decrement memory by one 将M中的值-1(M --) Operation: M - 1 -> M +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Zero Page | DEC Oper | C6 | 2 | 5 | | Zero Page,X | DEC Oper,X | D6 | 2 | 6 | | Absolute | DEC Oper | CE | 3 | 6 | | Absolute,X | DEC Oper,X | DE | 3 | 7 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if result is zero |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of the result is set |
22. DEX DEX Decrement index X by one 将X中的值-1(X --) Operation: X - 1 -> X +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | DEX | CA | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if X is zero |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of X is set |
23. DEY DEY Decrement index Y by one 将Y中的值-1(Y --) Operation: X - 1 -> Y +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | DEY | 88 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if Y is zero |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of Y is set |
24. EOR EOR "Exclusive-Or" memory with accumulator A XOR M,存于A Operation: A XOR M -> A +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | EOR #Oper | 49 | 2 | 2 | | Zero Page | EOR Oper | 45 | 2 | 3 | | Zero Page,X | EOR Oper,X | 55 | 2 | 4 | | Absolute | EOR Oper | 4D | 3 | 4 | | Absolute,X | EOR Oper,X | 5D | 3 | 4* | | Absolute,Y | EOR Oper,Y | 59 | 3 | 4* | | (Indirect,X) | EOR (Oper,X) | 41 | 2 | 6 | | (Indirect),Y | EOR (Oper),Y | 51 | 2 | 5* | +----------------+-----------------------+---------+---------+----------+
* 当操作跨内存页(page)的时候加1
C | Carry Flag | Not affected |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 set |
25. INC INC Increment memory by one 将M中的值+1(M ++) Operation: M + 1 -> M +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Zero Page | INC Oper | E6 | 2 | 5 | | Zero Page,X | INC Oper,X | F6 | 2 | 6 | | Absolute | INC Oper | EE | 3 | 6 | | Absolute,X | INC Oper,X | FE | 3 | 7 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if result is zero |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of the result is set |
26. INX INX Increment Index X by one 将X中的值+1(X ++) Operation: X + 1 -> X +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | INX | E8 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if X is zero |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of X is set |
27. INY INY Increment Index Y by one 将Y中的值+1(Y ++) Operation: X + 1 -> X +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | INY | C8 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if Y is zero |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of Y is set |
28. JMP JMP Jump to new location 跳到新地址 Operation: (PC + 1) -> PCL (PC + 2) -> PCH +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Absolute | JMP Oper | 4C | 3 | 3 | | Indirect | JMP (Oper) | 6C | 3 | 5 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
29. JSR JSR Jump to new location saving return address 跳到新地址,并保存返回地址(PUSH PC +2) Operation: PC + 2 toS, (PC + 1) -> PCL (PC + 2) -> PCH +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Absolute | JSR Oper | 20 | 3 | 6 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
30. LDA LDA Load accumulator with memory 将M中的值存到A Operation: M -> A +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | LDA #Oper | A9 | 2 | 2 | | Zero Page | LDA Oper | A5 | 2 | 3 | | Zero Page,X | LDA Oper,X | B5 | 2 | 4 | | Absolute | LDA Oper | AD | 3 | 4 | | Absolute,X | LDA Oper,X | BD | 3 | 4* | | Absolute,Y | LDA Oper,Y | B9 | 3 | 4* | | (Indirect,X) | LDA (Oper,X) | A1 | 2 | 6 | | (Indirect),Y | LDA (Oper),Y | B1 | 2 | 5* | +----------------+-----------------------+---------+---------+----------+ * 当操作跨内存页(page)的时候加1
C | Carry Flag | Not affected |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of A is set |
31. LDX LDX Load index X with memory 将M中的值存到X Operation: M -> X +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | LDX #Oper | A2 | 2 | 2 | | Zero Page | LDX Oper | A6 | 2 | 3 | | Zero Page,Y | LDX Oper,Y | B6 | 2 | 4 | | Absolute | LDX Oper | AE | 3 | 4 | | Absolute,Y | LDX Oper,Y | BE | 3 | 4* | +----------------+-----------------------+---------+---------+----------+ * 当操作跨内存页(page)的时候加1
C | Carry Flag | Not affected |
Z | Zero Flag | Set if X = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of X is set |
32. LDY LDY Load index Y with memory 将M中的值存到Y Operation: M -> Y +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | LDY #Oper | A0 | 2 | 2 | | Zero Page | LDY Oper | A4 | 2 | 3 | | Zero Page,X | LDY Oper,X | B4 | 2 | 4 | | Absolute | LDY Oper | AC | 3 | 4 | | Absolute,X | LDY Oper,X | BC | 3 | 4* | +----------------+-----------------------+---------+---------+----------+ * 当操作跨内存页(page)的时候加1
C | Carry Flag | Not affected |
Z | Zero Flag | Set if Y = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of Y is set |
33. LSR LSR Shift right one bit (memory or accumulator) 将M或A中的值左移1位 +-+-+-+-+-+-+-+-+ Operation: 0 -> |7|6|5|4|3|2|1|0| -> C +-+-+-+-+-+-+-+-+ +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Accumulator | LSR A | 4A | 1 | 2 | | Zero Page | LSR Oper | 46 | 2 | 5 | | Zero Page,X | LSR Oper,X | 56 | 2 | 6 | | Absolute | LSR Oper | 4E | 3 | 6 | | Absolute,X | LSR Oper,X | 5E | 3 | 7 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set to contents of old bit 0 |
Z | Zero Flag | Set if result = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of the result is set |
34. NOP NOP No operation 空指令,什么也不做 Operation: No Operation (2 cycles) +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | NOP | EA | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
35. ORA ORA "OR" memory with accumulator A OR M,存于A Operation: A OR M -> A +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | ORA #Oper | 09 | 2 | 2 | | Zero Page | ORA Oper | 05 | 2 | 3 | | Zero Page,X | ORA Oper,X | 15 | 2 | 4 | | Absolute | ORA Oper | 0D | 3 | 4 | | Absolute,X | ORA Oper,X | 1D | 3 | 4* | | Absolute,Y | ORA Oper,Y | 19 | 3 | 4* | | (Indirect,X) | ORA (Oper,X) | 01 | 2 | 6 | | (Indirect),Y | ORA (Oper),Y | 11 | 2 | 5 | +----------------+-----------------------+---------+---------+----------+ * 当操作跨内存页(page)的时候加1
C | Carry Flag | Not affected |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 set |
36. PHA PHA Push accumulator on stack PUSH A
Operation: PUSH A +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | PHA | 48 | 1 | 3 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
37. PHP PHP Push processor status on stack PUSH P Operation: PUSH P +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | PHP | 08 | 1 | 3 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
38. PLA PLA Pull accumulator from stack POP to A Operation: POP to A +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | PLA | 68 | 1 | 4 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of A is set |
39. PLP PLP Pull processor status from stack POP to P Operation: POP to P +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | PLP | 28 | 1 | 4 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set from stack |
Z | Zero Flag | Set from stack |
I | Interrupt Disable | Set from stack |
D | Decimal Mode Flag | Set from stack |
B | Break Command | Set from stack |
V | Overflow Flag | Set from stack |
N | Negative Flag | Set from stack |
40. ROL ROL Rotate one bit left (memory or accumulator) 左移M或A一位 +------------------------------+ | M or A | | +-+-+-+-+-+-+-+-+ +-+ | Operation: +-< |7|6|5|4|3|2|1|0| <- |C| <-+ +-+-+-+-+-+-+-+-+ +-+ +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Accumulator | ROL A | 2A | 1 | 2 | | Zero Page | ROL Oper | 26 | 2 | 5 | | Zero Page,X | ROL Oper,X | 36 | 2 | 6 | | Absolute | ROL Oper | 2E | 3 | 6 | | Absolute,X | ROL Oper,X | 3E | 3 | 7 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set to contents of old bit 7 |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of the result is set |
41. ROR ROR Rotate one bit right (memory or accumulator) 右移M或A一位 +------------------------------+ | | | +-+ +-+-+-+-+-+-+-+-+ | Operation: +-> |C| -> |7|6|5|4|3|2|1|0| >-+ +-+ +-+-+-+-+-+-+-+-+ +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Accumulator | ROR A | 6A | 1 | 2 | | Zero Page | ROR Oper | 66 | 2 | 5 | | Zero Page,X | ROR Oper,X | 76 | 2 | 6 | | Absolute | ROR Oper | 6E | 3 | 6 | | Absolute,X | ROR Oper,X | 7E | 3 | 7 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set to contents of old bit 0 |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of the result is set |
42. RTI RTI Return from interrupt 从中断返回(POP to P, POP to PC) Operation: POP to P, POP to PC +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | RTI | 4D | 1 | 6 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set from stack |
Z | Zero Flag | Set from stack |
I | Interrupt Disable | Set from stack |
D | Decimal Mode Flag | Set from stack |
B | Break Command | Set from stack |
V | Overflow Flag | Set from stack |
N | Negative Flag | Set from stack |
43. RTS RTS Return from subroutine 从分支返回(POP to PC, PC ++) Operation: POP to PC, PC + 1 -> PC +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | RTS | 60 | 1 | 6 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
44. SBC SBC Subtract memory from accumulator with borrow A-M,有借位参与,存于A Operation: A - M - C -> A 其中C为借位 +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Immediate | SBC #Oper | E9 | 2 | 2 | | Zero Page | SBC Oper | E5 | 2 | 3 | | Zero Page,X | SBC Oper,X | F5 | 2 | 4 | | Absolute | SBC Oper | ED | 3 | 4 | | Absolute,X | SBC Oper,X | FD | 3 | 4* | | Absolute,Y | SBC Oper,Y | F9 | 3 | 4* | | (Indirect,X) | SBC (Oper,X) | E1 | 2 | 6 | | (Indirect),Y | SBC (Oper),Y | F1 | 2 | 5 | +----------------+-----------------------+---------+---------+----------+ * 当操作跨内存页(page)的时候加1
C | Carry Flag | Clear if overflow in bit 7 |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Set if sign bit is incorrect |
N | Negative Flag | Set if bit 7 set |
45. SEC SEC Set carry flag 将C(进位标志)置为1 Operation: 1 -> C +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | SEC | 38 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Set to 1 |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
46. SED SED Set decimal mode 将D(十进制表示标志位)置为1 Operation: 1 -> D +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | SED | F8 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Set to 1 |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
47. SEI SEI Set interrupt disable status 将I(中断禁止标志)置为1
Operation: 1 -> I +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | SEI | 78 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Set to 1 |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
48. STA STA Store accumulator in memory 将A的值存于M Operation: A -> M +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Zero Page | STA Oper | 85 | 2 | 3 | | Zero Page,X | STA Oper,X | 95 | 2 | 4 | | Absolute | STA Oper | 8D | 3 | 4 | | Absolute,X | STA Oper,X | 9D | 3 | 5 | | Absolute,Y | STA Oper, Y | 99 | 3 | 5 | | (Indirect,X) | STA (Oper,X) | 81 | 2 | 6 | | (Indirect),Y | STA (Oper),Y | 91 | 2 | 6 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
49. STX STX Store index X in memory 将X的值存于M Operation: X -> M +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Zero Page | STX Oper | 86 | 2 | 3 | | Zero Page,Y | STX Oper,Y | 96 | 2 | 4 | | Absolute | STX Oper | 8E | 3 | 4 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
50. STY STY Store index Y in memory 将Y的值存于M Operation: Y -> M +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Zero Page | STY Oper | 84 | 2 | 3 | | Zero Page,X | STY Oper,X | 94 | 2 | 4 | | Absolute | STY Oper | 8C | 3 | 4 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
51. TAX TAX Transfer accumulator to index X 将A的值存于X Operation: A -> X +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | TAX | AA | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if X = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of X is set |
52. TAY TAY Transfer accumulator to index Y 将A的值存于Y Operation: A -> Y +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | TAY | A8 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if Y = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of Y is set |
53. TSX TSX Transfer stack pointer to index X 将SP的值存于X Operation: SP -> X +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | TSX | BA | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if X = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of X is set |
54. TXA TXA Transfer index X to accumulator 将X的值存于A Operation: X -> A +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | TXA | 8A | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of A is set |
55. TXS TXS Transfer index X to stack pointer 将X的值存于SP Operation: X -> SP +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | TXS | 9A | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Not affected |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Not affected |
56. TYA TYA Transfer index Y to accumulator 将Y的值存于A Operation: Y -> A +----------------+-----------------------+---------+---------+----------+ | Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles| +----------------+-----------------------+---------+---------+----------+ | Implied | TYA | 98 | 1 | 2 | +----------------+-----------------------+---------+---------+----------+
C | Carry Flag | Not affected |
Z | Zero Flag | Set if A = 0 |
I | Interrupt Disable | Not affected |
D | Decimal Mode Flag | Not affected |
B | Break Command | Not affected |
V | Overflow Flag | Not affected |
N | Negative Flag | Set if bit 7 of A is set |
说明性的代码
为了对以上的代码有个更直观的理解,借用了一小段简短的代码来说明一下每条指令具体的实现。注意这里只是简短地概述,只是为了有个大概的印象,并非完整地实现。完整地实现会在后面的章节中讨论。
首先定义变量和函数
src : 输入的内存地址,单字节 SET_SIGN(value) : 设置\清0 S(符号位),根据bit7 SET_ZERO(value) : 设置\清0 Z(零位),根据结果是否为0 SET_CARRY(condition) : 如果condition为真,则设置C(进位),否则清0 SET_OVERFLOW(condition) : ...设置V(溢出位)... SET_INTERRUPT(condition) : ...设置I(中断禁止位)... SET_BREAK(condition) : ...设置B(break位,用来区分软、硬中断)... SET_DECIMAL(condition) : ...设置D(decimal mode位)... IF_CARRY() } IF_OVERFLOW() } IF_SIGN() } 判断对应标志位的值 IF_ZERO() } ... } REL_ADDR(PC, src) : 返回相对地址,通过src与PC求和得到 SET_P(value) : 根据输入值设置P(状态寄存器) GET_P() : 读出P的值 POP() : 返回栈顶元素并出栈 PUSH(value) : 压栈
LOAD(address) : 从内存中读取一个字节 STORE(address, value) : 往内存中写入一个字节 CYCLES: 指令周期计数器,同样的指令会因计算结果而异(只在部分代码中演示) A = 寄存器A X = 寄存器X Y = 寄存器Y PC = 程序计数器 SP = 栈顶指针
/* 1. ADC 将内存中的值与A求和,存于A,有进位C参与其中 Operation: A + M + C -> A, C N Z C I D V / / / _ _ / */ unsigned int temp = src + A + (IF_CARRY() ? 1 : 0);//A + M + C SET_ZERO(temp & 0xff); //根据低16位设置Z.在decimal mode下无效 if (IF_DECIMAL())//decimal mode在NES下无效 { if (((A & 0xf) + (src & 0xf) + (IF_CARRY() ? 1 : 0)) > 9) temp += 6; SET_SIGN(temp); SET_OVERFLOW(!((A ^ src) & 0x80) && ((A ^ temp) & 0x80)); if (temp > 0x99) temp += 96; SET_CARRY(temp > 0x99); } else { SET_SIGN(temp);//设置S SET_OVERFLOW(!((A ^ src) & 0x80) && ((A ^ temp) & 0x80));//设置V。判断的是(A与src符号位相同)且(A与结果符号位不同),即比如两个正数相加产生了负数,中间肯定有溢出 SET_CARRY(temp > 0xff);//设置Z } A = (BYTE) temp;//存于A
/* 2. AND 将内存与A进行逻辑与,存于A Operation: A AND M -> A N Z C I D V / / _ _ _ _ */ src &= A; SET_SIGN(src); SET_ZERO(src); A = src;
/* 3.ASL 将内存中或A中的值左移1位 +-+-+-+-+-+-+-+-+ Operation: C <- |7|6|5|4|3|2|1|0| <- 0 +-+-+-+-+-+-+-+-+ N Z C I D V / / / _ _ _ */ SET_CARRY(src & 0x80);//根据原最高位判断C src <<= 1; src &= 0xff; SET_SIGN(src); SET_ZERO(src); //STORE src in memory or accumulator depending on addressing mode.
/* 4.BCC 判断C(进位标志)是否为0进行跳转 N Z C I D V Operation: Branch on C = 0 _ _ _ _ _ _ */ if (!IF_CARRY()) { CYCLES += ((PC & 0xFF00) != (REL_ADDR(PC, src) & 0xFF00) ? 2 : 1);//如果目的地址位于同一个内存页,则加1;如果位于不同页,则加2 PC = REL_ADDR(PC, src);//进行跳转 }
/* 5. BCS 判断C是否为1进行跳转 Operation: Branch on C = 1 N Z C I D V _ _ _ _ _ _ */ if (IF_CARRY()) { CYCLES += ((PC & 0xFF00) != (REL_ADDR(PC, src) & 0xFF00) ? 2 : 1); PC = REL_ADDR(PC, src); }
/* 6. BEQ 判断Z(zero标志位)是否为1进行跳转 N Z C I D V Operation: Branch on Z = 1 _ _ _ _ _ _ */ if (IF_ZERO()) { CYCLES += ((PC & 0xFF00) != (REL_ADDR(PC, src) & 0xFF00) ? 2 : 1); PC = REL_ADDR(PC, src); }
/* 7. BIT 内存M与A进行逻辑与,然后把M的Bit 6和Bit 7给P中的S与V标志位。 Operation: A AND M, M7 -> N, M6 -> V N Z C I D V M7 _ _ _ M6 Z位可能会被改变,取决于A AND M的结果。如果结果为0,则Z为1;如果结果非0,则Z为0. */ SET_SIGN(src); SET_OVERFLOW(0x40 & src); //根据bit6设置V SET_ZERO(src & A);
/* 8. BMI 判断N标志位(符号标志位)是否为1进行跳转 Operation: Branch on N = 1 N Z C I D V _ _ _ _ _ _ */ if (IF_SIGN()) { CYCLES += ((PC & 0xFF00) != (REL_ADDR(PC, src) & 0xFF00) ? 2 : 1); PC = REL_ADDR(PC, src); }
/* 9. BNE 判断Z标志位是否为0进行跳转 Operation: Branch on Z = 0 N Z C I D V _ _ _ _ _ _ */ if (!IF_ZERO()) { CYCLES += ((PC & 0xFF00) != (REL_ADDR(PC, src) & 0xFF00) ? 2 : 1); PC = REL_ADDR(PC, src); }
/* 10. BPL BPL Branch on result plus 判断N标志位是否为0进行跳转 Operation: Branch on N = 0 N Z C I D V _ _ _ _ _ _ */ if (!IF_SIGN()) { CYCLES += ((PC & 0xFF00) != (REL_ADDR(PC, src) & 0xFF00) ? 2 : 1); PC = REL_ADDR(PC, src); }
/* 11. BRK 产生软中断(对于PC+2和P进行压栈) Operation: Forced Interrupt, PUSH PC + 2, PUSH P N Z C I D V _ _ _ 1 _ _ */ PC ++;//PC + 2(PC为16位) PUSH((PC >> 8) & 0xff); //保存PC高字节(栈为8位,所以要分开push) PUSH(PC & 0xff);//保存PC低字节 SET_BREAK((1));//因为是软中断,设置BREAK位 PUSH(SR); SET_INTERRUPT((1));//设置I(中断禁止标志),防止新的中断产生 PC = (LOAD(0xFFFE) | (LOAD(0xFFFF) << 8));//跳转到vector table的入口地址(相当于中断处理函数入口地址),BRK指令属于IRQ中断,对应的是$FFFE-$FFFF
/* 12. BVC 判断V(溢出标志)是否为0进行跳转 Operation: Branch on V = 0 N Z C I D V _ _ _ _ _ _ */ if (!IF_OVERFLOW()) { CYCLES += ((PC & 0xFF00) != (REL_ADDR(PC, src) & 0xFF00) ? 2 : 1); PC = REL_ADDR(PC, src); }
/* 13. BVS 判断V是否为1进行跳转 Operation: Branch on V = 1 N Z C I D V _ _ _ _ _ _ */ if (IF_OVERFLOW()) { CYCLES += ((PC & 0xFF00) != (REL_ADDR(PC, src) & 0xFF00) ? 2 : 1); PC = REL_ADDR(PC, src); }
/* 14. CLC 清除C标志位 Operation: 0 -> C N Z C I D V _ _ 0 _ _ _ */ SET_CARRY((0));
/* 15. CLD 清除D标志位(十进制表示标志) Operation: 0 -> D N A C I D V _ _ _ _ 0 _ */ SET_DECIMAL((0));
/* 16. CLI 清除I标志位(中断禁止标志) Operation: 0 -> I N Z C I D V _ _ _ 0 _ _ */ SET_INTERRUPT((0));
/* 17. CLV 清除V标志位(溢出标志位) Operation: 0 -> V N Z C I D V _ _ _ _ _ 0 */ SET_OVERFLOW((0));
/* 18. CMP 比较内存与A(A-M) Operation: A - M N Z C I D V / / / _ _ _ */ src = A - src; SET_CARRY(src < 0x100); SET_SIGN(src); SET_ZERO(src &= 0xff);
/* 19. CPX 比较内存与X(X - M) N Z C I D V Operation: X - M / / / _ _ _ */ src = X - src; SET_CARRY(src < 0x100); SET_SIGN(src); SET_ZERO(src &= 0xff);
/* 20. CPY 比较内存与Y(Y - M) N Z C I D V Operation: Y - M / / / _ _ _ */ src = Y - src; SET_CARRY(src < 0x100); SET_SIGN(src); SET_ZERO(src &= 0xff);
/* 21. DEC 将M中的值-1(M --) Operation: M - 1 -> M N Z C I D V / / _ _ _ _ */ src = (src - 1) & 0xff; SET_SIGN(src); SET_ZERO(src); STORE(address, (src));
/* 22. DEX 将X中的值-1(X --) Operation: X - 1 -> X N Z C I D V / / _ _ _ _ */ unsigned src = X; src = (src - 1) & 0xff; SET_SIGN(src); SET_ZERO(src); X = (src);
/* 23. DEY 将Y中的值-1(Y --) Operation: X - 1 -> Y N Z C I D V / / _ _ _ _ */ unsigned src = Y; src = (src - 1) & 0xff; SET_SIGN(src); SET_ZERO(src); Y = (src);
/* 24. EOR A XOR M,存于A Operation: A XOR M -> A N Z C I D V / / _ _ _ _ */ src ^= A; SET_SIGN(src); SET_ZERO(src); A = src;
/* 25. INC 将M中的值+1(M ++) N Z C I D V Operation: M + 1 -> M / / _ _ _ _ */ src = (src + 1) & 0xff; SET_SIGN(src); SET_ZERO(src); STORE(address, (src));
/* 26. INX 将X中的值+1(X ++) N Z C I D V Operation: X + 1 -> X / / _ _ _ _ */ unsigned src = X; src = (src + 1) & 0xff; SET_SIGN(src); SET_ZERO(src); X = (src);
/* 27. INY 将Y中的值+1(Y ++) Operation: X + 1 -> X N Z C I D V / / _ _ _ _ */ unsigned src = Y; src = (src + 1) & 0xff; SET_SIGN(src); SET_ZERO(src); Y = (src);
/* 28. JMP 跳到新地址 Operation: (PC + 1) -> PCL N Z C I D V (PC + 2) -> PCH _ _ _ _ _ _ */ PC = (src);
/* 29. JSR 跳到新地址,并保存返回地址(PUSH PC +2) Operation: PC + 2 toS, (PC + 1) -> PCL N Z C I D V (PC + 2) -> PCH _ _ _ _ _ _ */ PC ++; PUSH((PC >> 8) & 0xff); /* Push return address onto the stack. */ PUSH(PC & 0xff); PC = (src);
/* 30. LDA 将M中的值存到A Operation: M -> A N Z C I D V / / _ _ _ _ */ SET_SIGN(src); SET_ZERO(src); A = (src);
/* 31. LDX 将M中的值存到X Operation: M -> X N Z C I D V / / _ _ _ _ */ SET_SIGN(src); SET_ZERO(src); X = (src);
/* 32. LDY 将M中的值存到Y N Z C I D V Operation: M -> Y / / _ _ _ _ */ SET_SIGN(src); SET_ZERO(src); Y = (src);
/* 33. LSR 将M或A中的值左移1位 +-+-+-+-+-+-+-+-+ Operation: 0 -> |7|6|5|4|3|2|1|0| -> C N Z C I D V +-+-+-+-+-+-+-+-+ 0 / / _ _ _ */ SET_CARRY(src & 0x01);//根据最低位设置C src >>= 1; SET_SIGN(src); SET_ZERO(src); //STORE src in memory or accumulator depending on addressing mode.
/* 34. NOP 空指令,什么也不做 N Z C I D V Operation: No Operation (2 cycles) _ _ _ _ _ _ */ //Nothing.
/* 35. ORA A OR M,存于A Operation: A OR M -> A N Z C I D V / / _ _ _ _ */ src |= A; SET_SIGN(src); SET_ZERO(src); A = src;
/* 36. PHA PUSH A Operation: PUSH A N Z C I D V _ _ _ _ _ _ */ src = A; PUSH(src);
/* 37. PHP PUSH P Operation: PUSH P N Z C I D V _ _ _ _ _ _ */ src = GET_P(); PUSH(src);
/* 38. PLA POP to A Operation: POP to A N Z C I D V _ _ _ _ _ _ */ src = POP(); SET_SIGN(src); SET_ZERO(src);
/* 39. PLP POP to P Operation: POP to P N Z C I D V 从栈中恢复 */ src = POP(); SET_P((src));
/* 40. ROL 左移M或A一位 +------------------------------+ | M or A | | +-+-+-+-+-+-+-+-+ +-+ | Operation: +-< |7|6|5|4|3|2|1|0| <- |C| <-+ N Z C I D V +-+-+-+-+-+-+-+-+ +-+ / / / _ _ _ */ src <<= 1; if (IF_CARRY()) src |= 0x1;//根据C设置最后一位 SET_CARRY(src > 0xff); src &= 0xff; SET_SIGN(src); SET_ZERO(src); //STORE src in memory or accumulator depending on addressing mode.
/* 41. ROR 右移M或A一位 +------------------------------+ | | | +-+ +-+-+-+-+-+-+-+-+ | Operation: +-> |C| -> |7|6|5|4|3|2|1|0| >-+ N Z C I D V +-+ +-+-+-+-+-+-+-+-+ / / / _ _ _ */ if (IF_CARRY()) src |= 0x100;//根据C设置最高位(在右移前,所以设置在bit8) SET_CARRY(src & 0x01); src >>= 1; SET_SIGN(src); SET_ZERO(src); //STORE src in memory or accumulator depending on addressing mode.
/* 42. RTI 从中断返回(POP to P, POP to PC) N Z C I D V Operation: POP to P, POP to PC 从栈中恢复 */ src = POP(); SET_P(src); src = POP(); src |= (POP() << 8);//把高低字节的PC拼接起来 PC = (src);
/* 43. RTS 从分支返回(POP to PC, PC ++) N Z C I D V Operation: POP to PC, PC + 1 -> PC _ _ _ _ _ _ */ src = POP(); src += ((POP()) << 8) + 1; /* Load return address from stack and add 1. */ PC = (src);
/* 44. SBC A-M,有借位参与,存于A Operation: A - M - C -> A N Z C I D V / / / _ _ / */ unsigned int temp = A - src - (IF_CARRY() ? 0 : 1);//A - M - C SET_SIGN(temp); SET_ZERO(temp & 0xff); SET_OVERFLOW(((A ^ temp) & 0x80) && ((A ^ src) & 0x80));//前面分析过了 if (IF_DECIMAL())//NES不支持decimal模式 { if ( ((A & 0xf) - (IF_CARRY() ? 0 : 1)) < (src & 0xf)) /* EP */ temp -= 6; if (temp > 0x99) temp -= 0x60; } SET_CARRY(temp < 0x100); A = (temp & 0xff);
/* 45. SEC 将C(进位标志)置为1 Operation: 1 -> C N Z C I D V _ _ 1 _ _ _ */ SET_CARRY((1));
/* 46. SED 将D(十进制表示标志位)置为1 N Z C I D V Operation: 1 -> D _ _ _ _ 1 _ */ SET_DECIMAL((1));
/* 47. SEI 将I(中断禁止标志)置为1 N Z C I D V Operation: 1 -> I _ _ _ 1 _ _ */ SET_INTERRUPT((1));
/* 48. STA 将A的值存于M Operation: A -> M N Z C I D V _ _ _ _ _ _ */ STORE(address, (src));
/* 49. STX 将X的值存于M Operation: X -> M N Z C I D V _ _ _ _ _ _ */ STORE(address, (src));
/* 50. STY 将Y的值存于M Operation: Y -> M N Z C I D V _ _ _ _ _ _ */ STORE(address, (src));
/* 51. TAX TAX Transfer accumulator to index X 将A的值存于X Operation: A -> X N Z C I D V / / _ _ _ _ */ unsigned src = A; SET_SIGN(src); SET_ZERO(src); X = (src);
/* 52. TAY TAY Transfer accumulator to index Y 将A的值存于Y Operation: A -> Y N Z C I D V / / _ _ _ _ */ unsigned src = A; SET_SIGN(src); SET_ZERO(src); Y = (src);
/* 53. TSX TSX Transfer stack pointer to index X 将SP的值存于X Operation: SP -> X N Z C I D V / / _ _ _ _ */ unsigned src = SP; SET_SIGN(src); SET_ZERO(src); X = (src);
/* 54. TXA TXA Transfer index X to accumulator 将X的值存于A N Z C I D V Operation: X -> A / / _ _ _ _ */ unsigned src = X; SET_SIGN(src); SET_ZERO(src); A = (src);
/* 55. TXS TXS Transfer index X to stack pointer 将X的值存于SP N Z C I D V Operation: X -> SP _ _ _ _ _ _ */ unsigned src = X; SP = (src);
/* 56. TYA TYA Transfer index Y to accumulator 将Y的值存于A Operation: Y -> A N Z C I D V / / _ _ _ _ */ unsigned src = Y; SET_SIGN(src); SET_ZERO(src); A = (src);
*关于unofficial(illegal) opcodes和具体的CPU模拟代码会在之后的章节中讨论
参考资料:
1. 6502 microprocessor(其中有多处把opcode中的'D'写成了'0')
5. Yane