⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.asm

📁 nes游戏模拟器
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	; 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 + -