mirror of
https://github.com/FranLMSP/snes.git
synced 2026-10-03 16:05:18 -04:00
adc direct page indirect and indirect long
This commit is contained in:
+117
-2
@@ -128,7 +128,26 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adc(&mut self, value: u16) {
|
fn adc8bcd(&mut self, value: u8) {
|
||||||
|
let carry = self.registers.get_carry_flag();
|
||||||
|
let a = self.registers.a as u8;
|
||||||
|
let carry_result = match a.checked_add(value) {
|
||||||
|
None => true,
|
||||||
|
Some(res) => match res.checked_add(carry as u8) {
|
||||||
|
None => true,
|
||||||
|
Some(_) => false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let result = a
|
||||||
|
.wrapping_add(value)
|
||||||
|
.wrapping_add(carry as u8);
|
||||||
|
self.registers.a = (self.registers.a & 0xFF00) | (result as u16);
|
||||||
|
self.registers.set_carry_flag(carry_result);
|
||||||
|
self.registers.set_negative_flag((result >> 7) == 1);
|
||||||
|
self.registers.set_zero_flag(result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn adc16bcd(&mut self, value: u16) {
|
||||||
let carry = self.registers.get_carry_flag();
|
let carry = self.registers.get_carry_flag();
|
||||||
let carry_result = match self.registers.a.checked_add(value) {
|
let carry_result = match self.registers.a.checked_add(value) {
|
||||||
None => true,
|
None => true,
|
||||||
@@ -137,10 +156,68 @@ impl CPU {
|
|||||||
Some(_) => false,
|
Some(_) => false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
self.registers.a = self.registers.a
|
let result = self.registers.a
|
||||||
.wrapping_add(value)
|
.wrapping_add(value)
|
||||||
.wrapping_add(carry as u16);
|
.wrapping_add(carry as u16);
|
||||||
|
self.registers.a = result;
|
||||||
self.registers.set_carry_flag(carry_result);
|
self.registers.set_carry_flag(carry_result);
|
||||||
|
self.registers.set_negative_flag((result >> 7) == 1);
|
||||||
|
self.registers.set_zero_flag(result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn adc8(&mut self, value: u8) {
|
||||||
|
let carry = self.registers.get_carry_flag();
|
||||||
|
let a = self.registers.a as u8;
|
||||||
|
let carry_result = match a.checked_add(value) {
|
||||||
|
None => true,
|
||||||
|
Some(res) => match res.checked_add(carry as u8) {
|
||||||
|
None => true,
|
||||||
|
Some(_) => false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let result = a
|
||||||
|
.wrapping_add(value)
|
||||||
|
.wrapping_add(carry as u8);
|
||||||
|
self.registers.a = (self.registers.a & 0xFF00) | (result as u16);
|
||||||
|
self.registers.set_carry_flag(carry_result);
|
||||||
|
self.registers.set_negative_flag((result >> 7) == 1);
|
||||||
|
self.registers.set_zero_flag(result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn adc16(&mut self, value: u16) {
|
||||||
|
let carry = self.registers.get_carry_flag();
|
||||||
|
let carry_result = match self.registers.a.checked_add(value) {
|
||||||
|
None => true,
|
||||||
|
Some(res) => match res.checked_add(carry as u16) {
|
||||||
|
None => true,
|
||||||
|
Some(_) => false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let result = self.registers.a
|
||||||
|
.wrapping_add(value)
|
||||||
|
.wrapping_add(carry as u16);
|
||||||
|
self.registers.a = result;
|
||||||
|
self.registers.set_carry_flag(carry_result);
|
||||||
|
self.registers.set_negative_flag((result >> 15) == 1);
|
||||||
|
self.registers.set_zero_flag(result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn adc(&mut self, value: u16) {
|
||||||
|
// if the M flag is set, perform 8 bit addition.
|
||||||
|
// Otherwise, 16 bit addition
|
||||||
|
if self.registers.get_memory_select_flag() {
|
||||||
|
if self.registers.get_decimal_mode_flag() {
|
||||||
|
self.adc8bcd(value as u8);
|
||||||
|
} else {
|
||||||
|
self.adc8(value as u8);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if self.registers.get_decimal_mode_flag() {
|
||||||
|
self.adc16bcd(value);
|
||||||
|
} else {
|
||||||
|
self.adc16(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adc_const(&mut self, bus: &Bus) {
|
fn adc_const(&mut self, bus: &Bus) {
|
||||||
@@ -202,6 +279,42 @@ impl CPU {
|
|||||||
self.adc(value as u16);
|
self.adc(value as u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn adc_dp_indirect(&mut self, bus: &Bus) {
|
||||||
|
let pointer = self.get_direct_page(bus) as u32;
|
||||||
|
let address = ((bus.read(pointer) as u32) << 8) | (bus.read(pointer + 1) as u32);
|
||||||
|
self.registers.pc = self.registers.pc.wrapping_add(2);
|
||||||
|
self.cycles += 3;
|
||||||
|
if self.registers.get_memory_select_flag() {
|
||||||
|
self.cycles += 1;
|
||||||
|
}
|
||||||
|
if address != 0 {
|
||||||
|
self.cycles += 1;
|
||||||
|
}
|
||||||
|
if self.registers.get_decimal_mode_flag() {
|
||||||
|
self.cycles += 1;
|
||||||
|
}
|
||||||
|
let value = bus.read(address);
|
||||||
|
self.adc(value as u16);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn adc_dp_indirect_long(&mut self, bus: &Bus) {
|
||||||
|
let pointer = self.get_direct_page(bus) as u32;
|
||||||
|
let address = ((bus.read(pointer) as u32) << 16) | ((bus.read(pointer + 1) as u32) << 8) | (bus.read(pointer + 2) as u32);
|
||||||
|
self.registers.pc = self.registers.pc.wrapping_add(2);
|
||||||
|
self.cycles += 3;
|
||||||
|
if self.registers.get_memory_select_flag() {
|
||||||
|
self.cycles += 1;
|
||||||
|
}
|
||||||
|
if address != 0 {
|
||||||
|
self.cycles += 1;
|
||||||
|
}
|
||||||
|
if self.registers.get_decimal_mode_flag() {
|
||||||
|
self.cycles += 1;
|
||||||
|
}
|
||||||
|
let value = bus.read(address);
|
||||||
|
self.adc(value as u16);
|
||||||
|
}
|
||||||
|
|
||||||
fn get_absolute(&self, bus: &Bus) -> u16 {
|
fn get_absolute(&self, bus: &Bus) -> u16 {
|
||||||
let pc = self.registers.get_pc_address();
|
let pc = self.registers.get_pc_address();
|
||||||
(bus.read(pc + 1) as u16) | ((bus.read(pc + 2) as u16) << 8)
|
(bus.read(pc + 1) as u16) | ((bus.read(pc + 2) as u16) << 8)
|
||||||
@@ -234,6 +347,8 @@ impl CPU {
|
|||||||
0x6D => self.adc_addr(bus),
|
0x6D => self.adc_addr(bus),
|
||||||
0x6F => self.adc_long(bus),
|
0x6F => self.adc_long(bus),
|
||||||
0x65 => self.adc_dp(bus),
|
0x65 => self.adc_dp(bus),
|
||||||
|
0x72 => self.adc_dp_indirect(bus),
|
||||||
|
0x67 => self.adc_dp_indirect_long(bus),
|
||||||
_ => todo!("Missing opcode implementation: {:02X}", opcode),
|
_ => todo!("Missing opcode implementation: {:02X}", opcode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user