SH-2 logical and bitwise instructions
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}