bits.rsannotatedbits.rssource209 lines · 6.4 KB · raw

SH-2 logical and bitwise instructions

3use crate::Sh2;
4use crate::bus::BusInterface;
5use crate::instructions::{rm, rn};
6use jgenesis_common::num::GetBit;
8impl Sh2 {
9    // AND Rm, Rn
10    // Logical and
11    pub(crate) fn and_rm_rn(&mut self, opcode: u16) {
12        let m = rm(opcode);
13        let n = rn(opcode);
14        self.registers.gpr[n] &= self.registers.gpr[m];
15    }
16
17    // AND #imm, R0
18    // Logical and
19    pub(crate) fn and_imm_r0(&mut self, opcode: u16) {
20        let imm: u32 = (opcode & 0xFF).into();
21        self.registers.gpr[0] &= imm;
22    }
23
24    // AND.B #imm @(R0,GBR)
25    // Logical and, in memory
26    pub(crate) fn and_imm_gbr_indexed(&mut self, opcode: u16, bus: &mut impl BusInterface) {
27        bus.increment_cycle_counter(2);
28
29        let imm = opcode as u8;
30        let address = self.registers.gbr.wrapping_add(self.registers.gpr[0]);
31        let value = self.read_byte(address, bus);
32        self.write_byte(address, value & imm, bus);
33    }
34
35    // OR Rm, Rn
36    // Logical or
37    pub(crate) fn or_rm_rn(&mut self, opcode: u16) {
38        let m = rm(opcode);
39        let n = rn(opcode);
40        self.registers.gpr[n] |= self.registers.gpr[m];
41    }
42
43    // OR #imm, R0
44    // Logical or
45    pub(crate) fn or_imm_r0(&mut self, opcode: u16) {
46        let imm: u32 = (opcode & 0xFF).into();
47        self.registers.gpr[0] |= imm;
48    }
49
50    // OR.B #imm @(R0,GBR)
51    // Logical or, in memory
52    pub(crate) fn or_imm_gbr_indexed(&mut self, opcode: u16, bus: &mut impl BusInterface) {
53        bus.increment_cycle_counter(2);
54
55        let imm = opcode as u8;
56        let address = self.registers.gbr.wrapping_add(self.registers.gpr[0]);
57        let value = self.read_byte(address, bus);
58        self.write_byte(address, value | imm, bus);
59    }
60
61    // XOR Rm, Rn
62    // Exclusive or
63    pub(crate) fn xor_rm_rn(&mut self, opcode: u16) {
64        let m = rm(opcode);
65        let n = rn(opcode);
66        self.registers.gpr[n] ^= self.registers.gpr[m];
67    }
68
69    // XOR #imm, R0
70    // Exclusive or
71    pub(crate) fn xor_imm_r0(&mut self, opcode: u16) {
72        let imm: u32 = (opcode & 0xFF).into();
73        self.registers.gpr[0] ^= imm;
74    }
75
76    // XOR.B #imm @(R0,GBR)
77    // Exclusive or, in memory
78    pub(crate) fn xor_imm_gbr_indexed(&mut self, opcode: u16, bus: &mut impl BusInterface) {
79        bus.increment_cycle_counter(2);
80
81        let imm = opcode as u8;
82        let address = self.registers.gbr.wrapping_add(self.registers.gpr[0]);
83        let value = self.read_byte(address, bus);
84        self.write_byte(address, value ^ imm, bus);
85    }
86
87    // NOT Rm, Rn
88    // Logical complement
89    pub(crate) fn not(&mut self, opcode: u16) {
90        let m = rm(opcode);
91        let n = rn(opcode);
92        self.registers.gpr[n] = !self.registers.gpr[m];
93    }
94
95    // SHLL Rn
96    // Logical shift left
97    pub(crate) fn shll(&mut self, opcode: u16) {
98        let n = rn(opcode);
99        self.registers.sr.t = self.registers.gpr[n].bit(31);
100        self.registers.gpr[n] <<= 1;
101    }
102
103    // SHLLn Rn
104    // Logical shift left by N bits
105    pub(crate) fn shlln<const N: usize>(&mut self, opcode: u16) {
106        let n = rn(opcode);
107        self.registers.gpr[n] <<= N;
108    }
109
110    // SHAR Rn
111    // Arithmetic shift right
112    pub(crate) fn shar(&mut self, opcode: u16) {
113        let n = rn(opcode);
114        self.registers.sr.t = self.registers.gpr[n].bit(0);
115        self.registers.gpr[n] = (self.registers.gpr[n] >> 1) | (self.registers.gpr[n] & (1 << 31));
116    }
117
118    // SHLR Rn
119    // Logical shift right
120    pub(crate) fn shlr(&mut self, opcode: u16) {
121        let n = rn(opcode);
122        self.registers.sr.t = self.registers.gpr[n].bit(0);
123        self.registers.gpr[n] >>= 1;
124    }
125
126    // SHLRn Rn
127    // Logical shift right by N bits
128    pub(crate) fn shlrn<const N: usize>(&mut self, opcode: u16) {
129        let n = rn(opcode);
130        self.registers.gpr[n] >>= N;
131    }
132
133    // ROTL Rn
134    // Rotate left
135    pub(crate) fn rotl(&mut self, opcode: u16) {
136        let n = rn(opcode);
137        self.registers.sr.t = self.registers.gpr[n].bit(31);
138        self.registers.gpr[n] = self.registers.gpr[n].rotate_left(1);
139    }
140
141    // ROTCL Rn
142    // Rotate with carry left
143    pub(crate) fn rotcl(&mut self, opcode: u16) {
144        let n = rn(opcode);
145        let carry_out = self.registers.gpr[n].bit(31);
146        self.registers.gpr[n] = (self.registers.gpr[n] << 1) | u32::from(self.registers.sr.t);
147        self.registers.sr.t = carry_out;
148    }
149
150    // ROTR Rn
151    // Rotate right
152    pub(crate) fn rotr(&mut self, opcode: u16) {
153        let n = rn(opcode);
154        let carry = self.registers.gpr[n].bit(0);
155        self.registers.sr.t = carry;
156        self.registers.gpr[n] = self.registers.gpr[n].rotate_right(1);
157    }
158
159    // ROTCR Rn
160    // Rotate with carry right
161    pub(crate) fn rotcr(&mut self, opcode: u16) {
162        let n = rn(opcode);
163        let carry_out = self.registers.gpr[n].bit(0);
164        self.registers.gpr[n] =
165            (self.registers.gpr[n] >> 1) | (u32::from(self.registers.sr.t) << 31);
166        self.registers.sr.t = carry_out;
167    }
168
169    // TST Rm, Rn
170    // Sets the T bit if (Rm & Rn) is 0
171    pub(crate) fn tst_rm_rn(&mut self, opcode: u16) {
172        let m = rm(opcode);
173        let n = rn(opcode);
174        self.registers.sr.t = self.registers.gpr[m] & self.registers.gpr[n] == 0;
175    }
176
177    // TST #imm, R0
178    // Sets the T bit if (#imm & R0) is 0
179    pub(crate) fn tst_imm_r0(&mut self, opcode: u16) {
180        let imm: u32 = (opcode & 0xFF).into();
181        self.registers.sr.t = imm & self.registers.gpr[0] == 0;
182    }
183
184    // TST.B #imm, @(R0,GBR)
185    // Sets the T bit if (#imm & MEM[GBR+R0]) is 0
186    pub(crate) fn tst_imm_gbr_indexed(&mut self, opcode: u16, bus: &mut impl BusInterface) {
187        bus.increment_cycle_counter(2);
188
189        let imm = opcode as u8;
190        let address = self.registers.gbr.wrapping_add(self.registers.gpr[0]);
191        let value = self.read_byte(address, bus);
192        self.registers.sr.t = imm & value == 0;
193    }
194
195    // TAS.B @Rn
196    // Tests the value at the specified address and sets bit 7
197    pub(crate) fn tas(&mut self, opcode: u16, bus: &mut impl BusInterface) {
198        bus.increment_cycle_counter(3);
199
200        let n = rn(opcode);
201        let address = self.registers.gpr[n];
202
203        // TAS never performs cached reads; read from the bus directly
204        let value = bus.read_byte(address & crate::EXTERNAL_ADDRESS_MASK, self.data_ctx);
205        self.write_byte(address, value | 0x80, bus);
206
207        self.registers.sr.t = value == 0;
208    }
209}