1use crate::sm83::bus::BusInterface; 2use crate::sm83::{Flags, Sm83}; 3use jgenesis_common::num::GetBit; 4 5macro_rules! impl_rla_op { 6 ($name:ident, thru_carry: $thru_carry:expr) => { 7 pub(super) fn $name(&mut self) { 8 let carry = self.registers.a.bit(7); 9 self.registers.a = if $thru_carry { 10 (self.registers.a << 1) | u8::from(self.registers.f.carry) 11 } else { 12 self.registers.a.rotate_left(1) 13 }; 14 self.registers.f = Flags { zero: false, subtract: false, half_carry: false, carry }; 15 } 16 }; 17} 18 19macro_rules! impl_rra_op { 20 ($name:ident, thru_carry: $thru_carry:expr) => { 21 pub(super) fn $name(&mut self) { 22 let carry = self.registers.a.bit(0); 23 self.registers.a = if $thru_carry { 24 (self.registers.a >> 1) | (u8::from(self.registers.f.carry) << 7) 25 } else { 26 self.registers.a.rotate_right(1) 27 }; 28 self.registers.f = Flags { zero: false, subtract: false, half_carry: false, carry }; 29 } 30 }; 31} 32 33impl Sm83 { 34 // AND: Bitwise and 35 pub(super) fn and_a_r<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 36 let operand = self.read_register(bus, opcode); 37 self.registers.a = and(self.registers.a, operand, &mut self.registers.f); 38 } 39 40 // AND: Bitwise and 41 pub(super) fn and_a_imm<B: BusInterface>(&mut self, bus: &mut B) { 42 let operand = self.fetch_operand(bus); 43 self.registers.a = and(self.registers.a, operand, &mut self.registers.f); 44 } 45 46 // OR: Bitwise inclusive or 47 pub(super) fn or_a_r<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 48 let operand = self.read_register(bus, opcode); 49 self.registers.a = or(self.registers.a, operand, &mut self.registers.f); 50 } 51 52 // OR: Bitwise inclusive or 53 pub(super) fn or_a_imm<B: BusInterface>(&mut self, bus: &mut B) { 54 let operand = self.fetch_operand(bus); 55 self.registers.a = or(self.registers.a, operand, &mut self.registers.f); 56 } 57 58 // XOR: Bitwise exclusive or 59 pub(super) fn xor_a_r<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 60 let operand = self.read_register(bus, opcode); 61 self.registers.a = xor(self.registers.a, operand, &mut self.registers.f); 62 } 63 64 // XOR: Bitwise exclusive or 65 pub(super) fn xor_a_imm<B: BusInterface>(&mut self, bus: &mut B) { 66 let operand = self.fetch_operand(bus); 67 self.registers.a = xor(self.registers.a, operand, &mut self.registers.f); 68 } 69 70 // CPL: Complement accumulator 71 pub(super) fn cpl(&mut self) { 72 self.registers.a = !self.registers.a; 73 74 self.registers.f.subtract = true; 75 self.registers.f.half_carry = true; 76 } 77 78 // RLCA: Rotate accumulator left 79 impl_rla_op!(rlca, thru_carry: false); 80 81 // RRCA: Rotate accumualtor right 82 impl_rra_op!(rrca, thru_carry: false); 83 84 // RLA: Rotate accumulator left through carry 85 impl_rla_op!(rla, thru_carry: true); 86 87 // RRA: Rotate accumulator right through carry 88 impl_rra_op!(rra, thru_carry: true); 89 90 // RLC: Rotate register left 91 pub(super) fn rlc_r<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 92 let value = self.read_register(bus, opcode); 93 let rotated = value.rotate_left(1); 94 self.write_register(bus, opcode, rotated); 95 96 self.registers.f = flags_for_shift_op(rotated, value.bit(7)); 97 } 98 99 // RRC: Rotate register right 100 pub(super) fn rrc_r<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 101 let value = self.read_register(bus, opcode); 102 let rotated = value.rotate_right(1); 103 self.write_register(bus, opcode, rotated); 104 105 self.registers.f = flags_for_shift_op(rotated, value.bit(0)); 106 } 107 108 // RL: Rotate register left through carry 109 pub(super) fn rl_r<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 110 let value = self.read_register(bus, opcode); 111 let rotated = (value << 1) | u8::from(self.registers.f.carry); 112 self.write_register(bus, opcode, rotated); 113 114 self.registers.f = flags_for_shift_op(rotated, value.bit(7)); 115 } 116 117 // RR: Rotate register right through carry 118 pub(super) fn rr_r<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 119 let value = self.read_register(bus, opcode); 120 let rotated = (value >> 1) | (u8::from(self.registers.f.carry) << 7); 121 self.write_register(bus, opcode, rotated); 122 123 self.registers.f = flags_for_shift_op(rotated, value.bit(0)); 124 } 125 126 // SLA: Shift left 127 pub(super) fn sla<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 128 let value = self.read_register(bus, opcode); 129 let shifted = value << 1; 130 self.write_register(bus, opcode, shifted); 131 132 self.registers.f = flags_for_shift_op(shifted, value.bit(7)); 133 } 134 135 // SRA: Arithmetic shift right 136 pub(super) fn sra<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 137 let value = self.read_register(bus, opcode); 138 let shifted = (value >> 1) | (value & 0x80); 139 self.write_register(bus, opcode, shifted); 140 141 self.registers.f = flags_for_shift_op(shifted, value.bit(0)); 142 } 143 144 // SRL: Logical shift right 145 pub(super) fn srl<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 146 let value = self.read_register(bus, opcode); 147 let shifted = value >> 1; 148 self.write_register(bus, opcode, shifted); 149 150 self.registers.f = flags_for_shift_op(shifted, value.bit(0)); 151 } 152 153 // SWAP: Swap nibbles 154 pub(super) fn swap<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 155 let value = self.read_register(bus, opcode); 156 self.write_register(bus, opcode, value.rotate_left(4)); 157 158 self.registers.f = 159 Flags { zero: value == 0, subtract: false, half_carry: false, carry: false }; 160 } 161 162 // BIT: Test bit 163 pub(super) fn bit<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 164 let value = self.read_register(bus, opcode); 165 let bit = (opcode >> 3) & 0x7; 166 167 self.registers.f.zero = !value.bit(bit); 168 self.registers.f.subtract = false; 169 self.registers.f.half_carry = true; 170 } 171 172 // SET: Set bit 173 pub(super) fn set<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 174 let value = self.read_register(bus, opcode); 175 let bit = (opcode >> 3) & 0x7; 176 self.write_register(bus, opcode, value | (1 << bit)); 177 } 178 179 // RES: Reset bit 180 pub(super) fn res<B: BusInterface>(&mut self, bus: &mut B, opcode: u8) { 181 let value = self.read_register(bus, opcode); 182 let bit = (opcode >> 3) & 0x7; 183 self.write_register(bus, opcode, value & !(1 << bit)); 184 } 185} 186 187fn flags_for_shift_op(value: u8, carry: bool) -> Flags { 188 Flags { zero: value == 0, subtract: false, half_carry: false, carry } 189} 190 191macro_rules! impl_bitwise_op { 192 ($name:ident, $op:tt, half_carry: $half_carry:expr) => { 193 fn $name(accumulator: u8, operand: u8, flags: &mut Flags) -> u8 { 194 let value = accumulator $op operand; 195 *flags = Flags { 196 zero: value == 0, 197 subtract: false, 198 half_carry: $half_carry, 199 carry: false, 200 }; 201 value 202 } 203 } 204} 205 206impl_bitwise_op!(and, &, half_carry: true); 207impl_bitwise_op!(or, |, half_carry: false); 208impl_bitwise_op!(xor, ^, half_carry: false);