📄 cpu.asm
字号:
; Test and set/clear the sign and zero flags.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * ASL. Opcodes 0A, 06, 16, 0E, 1E *
; ********************************************************************
CPU_ASL MACRO Operand:REQ
; Perform the operation.
shl BYTE PTR [Operand], 1
MODIFYFLAGS , , , C
mov al, [Operand]
test al, al
; Test and set/clear the flags.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * BCC. Opcode 90 *
; ********************************************************************
CPU_BCC MACRO Operand:REQ
; Test the carry flag.
test CPU.F, 1
; If the carry flag is clear, then branch.
.IF ZERO?
; If the operand is negative we subtract it from the PC,
; otherwise we need to add it to the PC.
.IF Operand & 10000000b
mov di, 0100h
sub di, Operand
sub CPU.P, di
.ELSE
add CPU.P, Operand
.ENDIF
.ENDIF
ENDM
; ********************************************************************
; * BCS. Opcode B0 *
; ********************************************************************
CPU_BCS MACRO Operand:REQ
; Test the carry flag.
test CPU.F, 00000001b
; If the carry flag is set, then branch.
.IF !ZERO?
; If the operand is negative we subtract it from the PC,
; otherwise we need to add it to the PC.
.IF Operand & 10000000b
mov di, 0100h
sub di, Operand
sub CPU.P, di
.ELSE
add CPU.P, Operand
.ENDIF
.ENDIF
ENDM
; ********************************************************************
; * BEQ. Opcode F0 *
; ********************************************************************
CPU_BEQ MACRO Operand:REQ
; Test the zero flag.
test CPU.F, 00000010b
; If the zero flag is set, then branch.
.IF !ZERO?
; If the operand is negative we subtract it from the PC,
; otherwise we need to add it to the PC.
.IF Operand & 10000000b
mov di, 0100h
sub di, Operand
sub CPU.P, di
.ELSE
add CPU.P, Operand
.ENDIF
.ENDIF
ENDM
; ********************************************************************
; * BIT. Opcodes 24, 2C *
; ********************************************************************
CPU_BIT MACRO Operand:REQ
; Save the operand for later and perform the bit operation
; which is really just an add instruction.
mov dl, Operand
and CPU.A, Operand
; Test and set/clear the zero flag.
MODIFYFLAGS S, , Z,
; Bit 7 of the operand is transferred to the sign flag.
; Bit 6 of the operand is transferred to the overflow flag.
and dl, 11000000b
and CPU.F, 00111111b
or CPU.F, dl
ENDM
; ********************************************************************
; * BMI. Opcode 30 *
; ********************************************************************
CPU_BMI MACRO Operand:REQ
; Test the sign flag.
test CPU.F, 10000000b
; If the sign flag is set, then branch.
.IF !ZERO?
; If the operand is negative we subtract it from the PC,
; otherwise we need to add it to the PC.
.IF Operand & 10000000b
mov di, 0100h
sub di, Operand
sub CPU.P, di
.ELSE
add CPU.P, Operand
.ENDIF
.ENDIF
ENDM
; ********************************************************************
; * BNE. Opcode D0 *
; ********************************************************************
CPU_BNE MACRO Operand:REQ
; Test the zero flag.
test CPU.F, 00000010b
; If the zero flag is clear, then branch.
.IF ZERO?
; If the operand is negative we subtract it from the PC,
; otherwise we need to add it to the PC.
.IF Operand & 10000000b
mov di, 0100h
sub di, Operand
sub CPU.P, di
.ELSE
add CPU.P, Operand
.ENDIF
.ENDIF
ENDM
; ********************************************************************
; * BPL. Opcode 10 *
; ********************************************************************
CPU_BPL MACRO Operand:REQ
; Test the sign flag.
test CPU.F, 10000000b
; If the sign flag is clear, then branch.
.IF ZERO?
; If the operand is negative we subtract it from the PC,
; otherwise we need to add it to the PC.
.IF Operand & 10000000b
mov di, 0100h
sub di, Operand
sub CPU.P, di
.ELSE
add CPU.P, Operand
.ENDIF
.ENDIF
ENDM
; ********************************************************************
; * BRK. Opcode 00 *
; ********************************************************************
CPU_BRK MACRO
; Push the PC+2 onto the stack high byte first.
mov bx, CPU.P
add bx, 2
PUSH_BYTE bh
PUSH_BYTE bl
; Push the flags onto the stack.
PUSH_BYTE CPU.F
; Set the new PC address byte getting the address from the
; break vector on the PRG-ROM.
GET_MEMORY_BYTE 0FFFEh
mov bl, al
GET_MEMORY_BYTE 0FFFFh
mov bh, al
mov CPU.P, bx
; Set the break flag.
or CPU.F, 00010000b
ENDM
; ********************************************************************
; * BVC. Opcode 50 *
; ********************************************************************
CPU_BVC MACRO Operand:REQ
; Test the overflow flag.
test CPU.F, 01000000b
; If the overflow flag is clear, then branch.
.IF ZERO?
; If the operand is negative we subtract it from the PC,
; otherwise we need to add it to the PC.
.IF Operand & 10000000b
mov di, 0100h
sub di, Operand
sub CPU.P, di
.ELSE
add CPU.P, Operand
.ENDIF
.ENDIF
ENDM
; ********************************************************************
; * BVS. Opcode 70 *
; ********************************************************************
CPU_BVS MACRO Operand:REQ
; Test the overflow flag.
test CPU.F, 01000000b
; If the overflow flag is set, then branch.
.IF !ZERO?
; If the operand is negative we subtract it from the PC,
; otherwise we need to add it to the PC.
.IF Operand & 10000000b
mov di, 0100h
sub di, Operand
sub CPU.P, di
.ELSE
add CPU.P, Operand
.ENDIF
.ENDIF
ENDM
; ********************************************************************
; * CLC. Opcode 18 *
; ********************************************************************
CPU_CLC MACRO
; Clear the carry flag.
and CPU.F, 11111110b
ENDM
; ********************************************************************
; * CLD. Opcode D8 *
; ********************************************************************
CPU_CLD MACRO
; Clear the decimal flag.
and CPU.F, 11110111b
ENDM
; ********************************************************************
; * CLI. Opcode 58 *
; ********************************************************************
CPU_CLI MACRO
; Clear the interrupt flag.
and CPU.F, 11111011b
ENDM
; ********************************************************************
; * CLV. Opcode B8 *
; ********************************************************************
CPU_CLV MACRO
; Clear the overflow flag.
and CPU.F, 10111111b
ENDM
; ********************************************************************
; * CMP. Opcodes C9, C5, D5, CD, DD, D9, C1, D1 *
; * CPX. Opcodes E0, E4, EC *
; * CPY. Opcodes C0, C4, CC *
; ********************************************************************
CPU_CP? MACRO byReg:REQ, Operand:REQ
; Compare and reverse the carry flag becuase the 6502 is
; opposite the Intel when it comes to subtraction.
cmp byReg, Operand
cmc
MODIFYFLAGS S, , Z, C
ENDM
; ********************************************************************
; * DEC. Opcodes C6, D6, CE, DE *
; ********************************************************************
CPU_DEC MACRO pbyMem:REQ
; Decrement the memory.
dec BYTE PTR [pbyMem]
; Now set the flags accordingly.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * DEX. Opcode CA *
; ********************************************************************
CPU_DEX MACRO
; Decrement the register.
dec CPU.X
; Now set the flags accordingly.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * DEY. Opcode 88 *
; ********************************************************************
CPU_DEY MACRO
; Decrement the register.
dec CPU.Y
; Now set the flags accordingly.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * EOR. Opcodes 49, 45, 55, 4D, 5D, 59, 41, 51 *
; ********************************************************************
CPU_EOR MACRO Operand:REQ
; Perform the operation.
xor CPU.A, Operand
; Test and set/clear the sign and zero flags.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * INC. Opcodes E6, F6, EE, FE *
; ********************************************************************
CPU_INC MACRO pbyMem:REQ
; Increment the memory.
inc BYTE PTR [pbyMem]
; Now set the flags accordingly.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * INX. Opcode E8 *
; ********************************************************************
CPU_INX MACRO
; Increment the register.
inc CPU.X
; Now set the flags accordingly.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * INY. Opcode C8 *
; ********************************************************************
CPU_INY MACRO
; Increment the register.
inc CPU.Y
; Now set the flags accordingly.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * JMP. Opcodes 4C, 6C *
; ********************************************************************
CPU_JMP MACRO Operand:REQ
; Set the new PC address.
mov CPU.P, Operand
ENDM
; ********************************************************************
; * JSR. Opcode 20 *
; ********************************************************************
CPU_JSR MACRO Operand:REQ
; Save the operand so it doesn't get overwritten.
push Operand
; Push the PC+2 onto the stack high byte first.
mov bx, CPU.P
add bx, 2
PUSH_BYTE bh
PUSH_BYTE bl
; Restore the operand set the new PC address.
pop Operand
mov CPU.P, Operand
ENDM
; ********************************************************************
; * LDA. Opcodes A9, A5, B5, AD, BD, B9, A1, B1 *
; * LDX. Opcodes A2, A6, B6, AE, BE *
; * LDY. Opcodes A0, A4, B4, AC, BC *
; ********************************************************************
CPU_LD? MACRO byReg:REQ, byData:REQ
; Move the operand into the A register.
mov byReg, byData
mov al, byReg
test al, al
; Test and Set/Clear the sign and zero flags.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * LSR. Opcodes 4A, 46, 56, 4E, 5E *
; ********************************************************************
CPU_LSR MACRO Operand:REQ
; Perform the operation.
shr BYTE PTR [Operand], 1
MODIFYFLAGS , , , C
mov al, [Operand]
test al, al
; Test and set/clear the flags.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * ORA. Opcodes 09, 05, 15, 0D, 1D, 19, 01, 11 *
; ********************************************************************
CPU_ORA MACRO Operand:REQ
; Perform the operation.
or CPU.A, Operand
; Test and set/clear the sign and zero flags.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * PHA. Opcode 48 *
; ********************************************************************
CPU_PHA MACRO
; Push the A register onto the stack.
PUSH_BYTE CPU.A
ENDM
; ********************************************************************
; * PHP. Opcode 08 *
; ********************************************************************
CPU_PHP MACRO
; Push the flags register onto the stack.
PUSH_BYTE CPU.F
ENDM
; ********************************************************************
; * PLA. Opcode 68 *
; ********************************************************************
CPU_PLA MACRO
; Pop the A register from the stack.
POP_BYTE CPU.A
; Now set the flags
mov al, CPU.A
test al, al
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * PLP. Opcode 28 *
; ********************************************************************
CPU_PLP MACRO
; Pop the flags register from the stack.
POP_BYTE CPU.F
ENDM
; ********************************************************************
; * ROL. Opcodes 2A, 26, 36, 2E, 3E *
; ********************************************************************
CPU_ROL MACRO Operand:REQ
; Set/clear the carry flag on the real cpu.
mov dl, CPU.F
shr dl, 1
; Perform the operation.
rcl BYTE PTR [Operand], 1
MODIFYFLAGS , , , C
mov al, [Operand]
test al, al
; Test and set/clear the flags.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * ROR. Opcodes 6A, 66, 76, 6E, 7E *
; ********************************************************************
CPU_ROR MACRO Operand:REQ
; Set/clear the carry flag on the real cpu.
mov dl, CPU.F
shr dl, 1
; Perform the operation.
rcr BYTE PTR [Operand], 1
MODIFYFLAGS , , , C
mov al, [Operand]
test al, al
; Test and set/clear the flags.
MODIFYFLAGS S, , Z,
ENDM
; ********************************************************************
; * RTI. Opcode 4D *
; ********************************************************************
CPU_RTI MACRO
; Pop the flags register from the stack.
POP_BYTE CPU.F
; Pop the PC from the stack low byte first.
POP_BYTE bl
POP_BYTE bh
; Set the PC to the new address.
mov CPU.P, bx
ENDM
; ********************************************************************
; * RTS. Opcode 60 *
; ********************************************************************
CPU_RTS MACRO
; Pop the PC from the stack low byte first.
POP_BYTE bl
POP_BYTE bh
; Set the PC to the new address.
mov CPU.P, bx
ENDM
; ********************************************************************
; * SBC. Opcodes E9, E5, F5, ED, FD, F9, E1, F1 *
; ********************************************************************
CPU_SBC MACRO Operand:REQ
; Move the NES's carry flag into the real cpu's carry flag.
mov dl, CPU.F
shr dl, 1
cmc
; Now subtract the operand from the A register with the carry flag.
sbb CPU.A, Operand
cmc
MODIFYFLAGS S, V, Z, C
ENDM
; ********************************************************************
; * SEC. Opcode 38 *
; ********************************************************************
CPU_SEC MACRO
; Set the carry flag.
or CPU.F, 00000001b
ENDM
; ********************************************************************
; * SED. Opcode F8 *
; ********************************************************************
CPU_SED MACRO
; Set the decimal flag.
or CPU.F, 00001000b
ENDM
; ********************************************************************
; * SEI. Opcode 78 *
; ********************************************************************
CPU_SEI MACRO
; Set the interrupt flag.
or CPU.F, 00000100b
ENDM
; ********************************************************************
; * STA. Opcodes 85, 95, 8D, 9D, 99, 81, 91 *
; * STX. Opcodes 86, 96, 8E *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -