-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconditionalBranchOpcodes.go
218 lines (169 loc) · 5.83 KB
/
conditionalBranchOpcodes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
package nmos6502
/*
BCC - Branch on Carry Clear
branch on C = 0
N Z C I D V
- - - - - -
addressing assembler opc bytes cycles
relative BCC oper 90 2 2**
*/
func (cpu *CPU) opcode0x90() (byte, bool) { // BCC Relative
offset := int8(cpu.fetch()) // Fetch the relative offset as a signed byte
if cpu.Status&Carry == 0 { // Check if the carry flag is clear
oldPC := cpu.PC
cpu.PC += uint16(offset) // Add the offset to the program counter
// Additional cycle if branch occurs to a new page
if (oldPC & 0xFF00) != (cpu.PC & 0xFF00) {
return 3, false // BCC takes 3 cycles if a page boundary is crossed
}
return 2, false // BCC takes 2 cycles if no page boundary is crossed
}
return 2, false // BCC takes 2 cycles if no branch is taken
}
/*
BCS - Branch on Carry Set
branch on C = 1
N Z C I D V
- - - - - -
addressing assembler opc bytes cycles
relative BCS oper B0 2 2**
*/
func (cpu *CPU) opcode0xB0() (byte, bool) { // BCS Relative
offset := int8(cpu.fetch()) // Fetch the relative offset as a signed byte
if cpu.Status&Carry != 0 { // Check if the carry flag is set
oldPC := cpu.PC
cpu.PC += uint16(offset) // Add the offset to the program counter
// Additional cycle if branch occurs to a new page
if (oldPC & 0xFF00) != (cpu.PC & 0xFF00) {
return 3, false // BCS takes 3 cycles if a page boundary is crossed
}
return 2, false // BCS takes 2 cycles if no page boundary is crossed
}
return 2, false // BCS takes 2 cycles if no branch is taken
}
/*
BEQ - Branch on Result Zero
branch on Z = 1
N Z C I D V
- - - - - -
addressing assembler opc bytes cycles
relative BEQ oper F0 2 2**
*/
func (cpu *CPU) opcode0xF0() (byte, bool) { // BEQ Relative
offset := int8(cpu.fetch()) // Fetch the relative offset as a signed byte
if cpu.Status&Zero != 0 { // Check if the zero flag is set
oldPC := cpu.PC
cpu.PC += uint16(offset) // Add the offset to the program counter
// Additional cycle if branch occurs to a new page
if (oldPC & 0xFF00) != (cpu.PC & 0xFF00) {
return 3, false // BEQ takes 3 cycles if a page boundary is crossed
}
return 2, false // BEQ takes 2 cycles if no page boundary is crossed
}
return 2, false // BEQ takes 2 cycles if no branch is taken
}
/*
BMI - Branch on Result Minus
branch on N = 1
N Z C I D V
- - - - - -
addressing assembler opc bytes cycles
relative BMI oper 30 2 2**
*/
func (cpu *CPU) opcode0x30() (byte, bool) { // BMI Relative
offset := int8(cpu.fetch()) // Fetch the relative offset as a signed byte
if cpu.Status&Negative != 0 { // Check if the negative flag is set
oldPC := cpu.PC
cpu.PC += uint16(offset) // Add the offset to the program counter
// Additional cycle if branch occurs to a new page
if (oldPC & 0xFF00) != (cpu.PC & 0xFF00) {
return 3, false // BMI takes 3 cycles if a page boundary is crossed
}
return 2, false // BMI takes 2 cycles if no page boundary is crossed
}
return 2, false // BMI takes 2 cycles if no branch is taken
}
/*
BNE - Branch on Result not Zero
branch on Z = 0
N Z C I D V
- - - - - -
addressing assembler opc bytes cycles
relative BNE oper D0 2 2**
*/
func (cpu *CPU) opcode0xD0() (byte, bool) { // BNE Relative
offset := int8(cpu.fetch()) // Fetch the relative offset as a signed byte
if cpu.Status&Zero == 0 { // Check if the zero flag is clear
oldPC := cpu.PC
cpu.PC += uint16(offset) // Add the offset to the program counter
// Additional cycle if branch occurs to a new page
if (oldPC & 0xFF00) != (cpu.PC & 0xFF00) {
return 3, false // BNE takes 3 cycles if a page boundary is crossed
}
return 2, false // BNE takes 2 cycles if no page boundary is crossed
}
return 2, false // BNE takes 2 cycles if no branch is taken
}
/*
BPL - Branch on Result Plus
branch on N = 0
N Z C I D V
- - - - - -
addressing assembler opc bytes cycles
relative BPL oper 10 2 2**
*/
func (cpu *CPU) opcode0x10() (byte, bool) { // BPL Relative
offset := int8(cpu.fetch()) // Fetch the relative offset as a signed byte
if cpu.Status&Negative == 0 { // Check if the negative flag is clear
oldPC := cpu.PC
cpu.PC += uint16(offset) // Add the offset to the program counter
// Additional cycle if branch occurs to a new page
if (oldPC & 0xFF00) != (cpu.PC & 0xFF00) {
return 3, false // BPL takes 3 cycles if a page boundary is crossed
}
return 2, false // BPL takes 2 cycles if no page boundary is crossed
}
return 2, false // BPL takes 2 cycles if no branch is taken
}
/*
BVC - Branch on Overflow Clear
branch on V = 0
N Z C I D V
- - - - - -
addressing assembler opc bytes cycles
relative BVC oper 50 2 2**
*/
func (cpu *CPU) opcode0x50() (byte, bool) { // BVC Relative
offset := int8(cpu.fetch()) // Fetch the relative offset as a signed byte
if cpu.Status&Overflow == 0 { // Check if the overflow flag is clear
oldPC := cpu.PC
cpu.PC += uint16(offset) // Add the offset to the program counter
// Additional cycle if branch occurs to a new page
if (oldPC & 0xFF00) != (cpu.PC & 0xFF00) {
return 3, false // BVC takes 3 cycles if a page boundary is crossed
}
return 2, false // BVC takes 2 cycles if no page boundary is crossed
}
return 2, false // BVC takes 2 cycles if no branch is taken
}
/*
BVS - Branch on Overflow Set
branch on V = 1
N Z C I D V
- - - - - -
addressing assembler opc bytes cycles
relative BVS oper 70 2 2**
*/
func (cpu *CPU) opcode0x70() (byte, bool) { // BVS Relative
offset := int8(cpu.fetch()) // Fetch the relative offset as a signed byte
if cpu.Status&Overflow != 0 { // Check if the overflow flag is clear
oldPC := cpu.PC
cpu.PC += uint16(offset) // Add the offset to the program counter
// Additional cycle if branch occurs to a new page
if (oldPC & 0xFF00) != (cpu.PC & 0xFF00) {
return 3, false // BVS takes 3 cycles if a page boundary is crossed
}
return 2, false // BVS takes 2 cycles if no page boundary is crossed
}
return 2, false // BVS takes 2 cycles if no branch is taken
}