bits.rsannotatedbits.rssource256 lines · 6.6 KB · raw
1#[allow(clippy::wildcard_imports)]
2use super::*;

BIT: Test bits (8-bit) Immediate gets a separate implementation because it doesn't set the N and V flags

6impl_read_op_u8!(
7    [immediate -> bit_immediate_u8]
8    (|registers, value| {
9        registers.p.zero = (registers.a as u8) & value == 0;
10    })
11);

BIT: Test bits (16-bit) Immediate gets a separate implementation because it doesn't set the N and V flags

15impl_read_op_u16!(
16    [immediate -> bit_immediate_u16]
17    (|registers, value| {
18        registers.p.zero = registers.a & value == 0;
19    })
20);

BIT: Test bits (8-bit)

23impl_read_op_u8!(
24    [
25        direct_page -> bit_direct_page_u8,
26        direct_page_x -> bit_direct_page_x_u8,
27        absolute -> bit_absolute_u8,
28        absolute_x -> bit_absolute_x_u8,
29    ]
30    (|registers, value| {
31        registers.p.zero = (registers.a as u8) & value == 0;
32        registers.p.negative = value.sign_bit();
33        registers.p.overflow = value.bit(6);
34    })
35);

BIT: Test bits (16-bit)

38impl_read_op_u16!(
39    [
40        direct_page -> bit_direct_page_u16,
41        direct_page_x -> bit_direct_page_x_u16,
42        absolute -> bit_absolute_u16,
43        absolute_x -> bit_absolute_x_u16,
44    ]
45    (|registers, value| {
46        registers.p.zero = registers.a & value == 0;
47        registers.p.negative = value.sign_bit();
48        registers.p.overflow = value.bit(14);
49    })
50);

TRB: Test and reset bits (8-bit)

53impl_modify_op_u8!(
54    [
55        direct_page -> trb_direct_page_u8,
56        absolute -> trb_absolute_u8,
57    ]
58    (|registers, value| {
59        let a_lsb = registers.a as u8;
60        let test = a_lsb & value;
61        registers.p.zero = test == 0;
62
63        value & !a_lsb
64    })
65);

TRB: Test and reset bits (16-bit)

68impl_modify_op_u16!(
69    [
70        direct_page -> trb_direct_page_u16,
71        absolute -> trb_absolute_u16,
72    ]
73    (|registers, value| {
74        registers.p.zero = registers.a & value == 0;
75        value & !registers.a
76    })
77);

TSB: Test and set bits (8-bit)

80impl_modify_op_u8!(
81    [
82        direct_page -> tsb_direct_page_u8,
83        absolute -> tsb_absolute_u8,
84    ]
85    (|registers, value| {
86        let a_lsb = registers.a as u8;
87        let test = a_lsb & value;
88        registers.p.zero = test == 0;
89
90        value | a_lsb
91    })
92);

TSB: Test and set bits (16-bit)

95impl_modify_op_u16!(
96    [
97        direct_page -> tsb_direct_page_u16,
98        absolute -> tsb_absolute_u16,
99    ]
100    (|registers, value| {
101        registers.p.zero = registers.a & value == 0;
102        value | registers.a
103    })
104);

ASL: Arithmetic shift left (8-bit)

107impl_modify_op_u8!(
108    [
109        accumulator -> asl_accumulator_u8,
110        direct_page -> asl_direct_page_u8,
111        direct_page_x -> asl_direct_page_x_u8,
112        absolute -> asl_absolute_u8,
113        absolute_x -> asl_absolute_x_u8,
114    ]
115    (|registers, value| {
116        let result = value << 1;
117        registers.p.zero = result == 0;
118        registers.p.negative = result.sign_bit();
119        registers.p.carry = value.sign_bit();
120
121        result
122    })
123);

ASL: Arithmetic shift left (16-bit)

126impl_modify_op_u16!(
127    [
128        accumulator -> asl_accumulator_u16,
129        direct_page -> asl_direct_page_u16,
130        direct_page_x -> asl_direct_page_x_u16,
131        absolute -> asl_absolute_u16,
132        absolute_x -> asl_absolute_x_u16,
133    ]
134    (|registers, value| {
135        let result = value << 1;
136        registers.p.zero = result == 0;
137        registers.p.negative = result.sign_bit();
138        registers.p.carry = value.sign_bit();
139
140        result
141    })
142);

LSR: Logical shift right (8-bit)

145impl_modify_op_u8!(
146    [
147        accumulator -> lsr_accumulator_u8,
148        direct_page -> lsr_direct_page_u8,
149        direct_page_x -> lsr_direct_page_x_u8,
150        absolute -> lsr_absolute_u8,
151        absolute_x -> lsr_absolute_x_u8,
152    ]
153    (|registers, value| {
154        let result = value >> 1;
155        registers.p.zero = result == 0;
156        registers.p.negative = result.sign_bit();
157        registers.p.carry = value.bit(0);
158
159        result
160    })
161);

LSR: Logical shift right (16-bit)

164impl_modify_op_u16!(
165    [
166        accumulator -> lsr_accumulator_u16,
167        direct_page -> lsr_direct_page_u16,
168        direct_page_x -> lsr_direct_page_x_u16,
169        absolute -> lsr_absolute_u16,
170        absolute_x -> lsr_absolute_x_u16,
171    ]
172    (|registers, value| {
173        let result = value >> 1;
174        registers.p.zero = result == 0;
175        registers.p.negative = result.sign_bit();
176        registers.p.carry = value.bit(0);
177
178        result
179    })
180);

ROL: Rotate left (8-bit)

183impl_modify_op_u8!(
184    [
185        accumulator -> rol_accumulator_u8,
186        direct_page -> rol_direct_page_u8,
187        direct_page_x -> rol_direct_page_x_u8,
188        absolute -> rol_absolute_u8,
189        absolute_x -> rol_absolute_x_u8,
190    ]
191    (|registers, value| {
192        let result = (value << 1) | u8::from(registers.p.carry);
193        registers.p.zero = result == 0;
194        registers.p.negative = result.sign_bit();
195        registers.p.carry = value.sign_bit();
196
197        result
198    })
199);

ROL: Rotate left (16-bit)

202impl_modify_op_u16!(
203    [
204        accumulator -> rol_accumulator_u16,
205        direct_page -> rol_direct_page_u16,
206        direct_page_x -> rol_direct_page_x_u16,
207        absolute -> rol_absolute_u16,
208        absolute_x -> rol_absolute_x_u16,
209    ]
210    (|registers, value| {
211        let result = (value << 1) | u16::from(registers.p.carry);
212        registers.p.zero = result == 0;
213        registers.p.negative = result.sign_bit();
214        registers.p.carry = value.sign_bit();
215
216        result
217    })
218);

ROR: Rotate right (8-bit)

221impl_modify_op_u8!(
222    [
223        accumulator -> ror_accumulator_u8,
224        direct_page -> ror_direct_page_u8,
225        direct_page_x -> ror_direct_page_x_u8,
226        absolute -> ror_absolute_u8,
227        absolute_x -> ror_absolute_x_u8,
228    ]
229    (|registers, value| {
230        let result = (value >> 1) | (u8::from(registers.p.carry) << 7);
231        registers.p.zero = result == 0;
232        registers.p.negative = result.sign_bit();
233        registers.p.carry = value.bit(0);
234
235        result
236    })
237);

ROR: Rotate right (16-bit)

240impl_modify_op_u16!(
241    [
242        accumulator -> ror_accumulator_u16,
243        direct_page -> ror_direct_page_u16,
244        direct_page_x -> ror_direct_page_x_u16,
245        absolute -> ror_absolute_u16,
246        absolute_x -> ror_absolute_x_u16,
247    ]
248    (|registers, value| {
249        let result = (value >> 1) | (u16::from(registers.p.carry) << 15);
250        registers.p.zero = result == 0;
251        registers.p.negative = result.sign_bit();
252        registers.p.carry = value.bit(0);
253
254        result
255    })
256);