NES模拟器开发 - 资料归纳整理 - 指令集篇

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')

2. 6502 opcode matrix

3. NES Documentation

4. Another NES Documentation

5. Yane

 

你可能感兴趣的:(模拟器)