rotate instructions
This commit is contained in:
parent
d1dae1aa73
commit
df8acbfa32
1 changed files with 63 additions and 4 deletions
|
@ -13,6 +13,11 @@ enum FLAGS {
|
||||||
C = 4,
|
C = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Direction {
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CPU {
|
pub struct CPU {
|
||||||
pub memory: Memory,
|
pub memory: Memory,
|
||||||
pub state: State,
|
pub state: State,
|
||||||
|
@ -43,7 +48,9 @@ impl CPU {
|
||||||
self.state.bc.as_u8s.left = self.sub_u8s(self.state.bc.as_u8s.left, 1)
|
self.state.bc.as_u8s.left = self.sub_u8s(self.state.bc.as_u8s.left, 1)
|
||||||
},
|
},
|
||||||
0x06 => self.state.bc.as_u8s.left = self.ld_immediate_byte(),
|
0x06 => self.state.bc.as_u8s.left = self.ld_immediate_byte(),
|
||||||
0x07 => panic!("RCLA rotate instruction: 0x07"),
|
0x07 => unsafe {
|
||||||
|
self.state.af.as_u8s.left = self.rlc(self.state.af.as_u8s.left, Direction::Left)
|
||||||
|
},
|
||||||
0x08 => unsafe {
|
0x08 => unsafe {
|
||||||
let address = self.ld_immediate_word().as_u16;
|
let address = self.ld_immediate_word().as_u16;
|
||||||
let word = self.state.sp;
|
let word = self.state.sp;
|
||||||
|
@ -61,7 +68,9 @@ impl CPU {
|
||||||
self.state.bc.as_u8s.right = self.sub_u8s(self.state.bc.as_u8s.right, 0x1)
|
self.state.bc.as_u8s.right = self.sub_u8s(self.state.bc.as_u8s.right, 0x1)
|
||||||
},
|
},
|
||||||
0x0E => self.state.bc.as_u8s.right = self.ld_immediate_byte(),
|
0x0E => self.state.bc.as_u8s.right = self.ld_immediate_byte(),
|
||||||
0x0F => panic!("RRCA rotate instruction: 0x0F"),
|
0x0F => unsafe {
|
||||||
|
self.state.af.as_u8s.left = self.rlc(self.state.af.as_u8s.left, Direction::Right)
|
||||||
|
},
|
||||||
0x10 => panic!("STOP instruction"),
|
0x10 => panic!("STOP instruction"),
|
||||||
0x11 => self.state.de = self.ld_immediate_word(),
|
0x11 => self.state.de = self.ld_immediate_word(),
|
||||||
0x12 => unsafe {
|
0x12 => unsafe {
|
||||||
|
@ -77,7 +86,9 @@ impl CPU {
|
||||||
self.state.de.as_u8s.left = self.sub_u8s(self.state.de.as_u8s.left, 0x1)
|
self.state.de.as_u8s.left = self.sub_u8s(self.state.de.as_u8s.left, 0x1)
|
||||||
},
|
},
|
||||||
0x16 => self.state.de.as_u8s.left = self.ld_immediate_byte(),
|
0x16 => self.state.de.as_u8s.left = self.ld_immediate_byte(),
|
||||||
0x17 => panic!("RLA rotate instruction: 0x17"),
|
0x17 => unsafe {
|
||||||
|
self.state.af.as_u8s.left = self.rl(self.state.af.as_u8s.left, Direction::Left);
|
||||||
|
},
|
||||||
0x18 => unsafe {
|
0x18 => unsafe {
|
||||||
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
|
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
|
||||||
self.state.pc.as_u16 = self.add_u16s(self.state.pc.as_u16, t)
|
self.state.pc.as_u16 = self.add_u16s(self.state.pc.as_u16, t)
|
||||||
|
@ -97,7 +108,9 @@ impl CPU {
|
||||||
self.state.de.as_u8s.right = self.sub_u8s(self.state.de.as_u8s.right, 1)
|
self.state.de.as_u8s.right = self.sub_u8s(self.state.de.as_u8s.right, 1)
|
||||||
},
|
},
|
||||||
0x1E => self.state.de.as_u8s.right = self.ld_immediate_byte(),
|
0x1E => self.state.de.as_u8s.right = self.ld_immediate_byte(),
|
||||||
0x1F => panic!("RRA rotate instruction: 0x1F"),
|
0x1F => unsafe {
|
||||||
|
self.state.af.as_u8s.left = self.rl(self.state.af.as_u8s.left, Direction::Right);
|
||||||
|
},
|
||||||
0x20 => {
|
0x20 => {
|
||||||
let jump_size = self.ld_immediate_byte();
|
let jump_size = self.ld_immediate_byte();
|
||||||
if self.get_flag(FLAGS::Z) == 0 {
|
if self.get_flag(FLAGS::Z) == 0 {
|
||||||
|
@ -846,6 +859,9 @@ impl CPU {
|
||||||
|
|
||||||
fn cb_subop(&mut self, subop: u8) {
|
fn cb_subop(&mut self, subop: u8) {
|
||||||
match subop {
|
match subop {
|
||||||
|
0x11 => unsafe {
|
||||||
|
self.state.bc.as_u8s.right = self.rl(self.state.bc.as_u8s.right, Direction::Left)
|
||||||
|
},
|
||||||
0x7C => unsafe {
|
0x7C => unsafe {
|
||||||
self.set_or_clear_flag(FLAGS::Z, !get_bit(self.state.hl.as_u8s.left, 7))
|
self.set_or_clear_flag(FLAGS::Z, !get_bit(self.state.hl.as_u8s.left, 7))
|
||||||
},
|
},
|
||||||
|
@ -861,6 +877,27 @@ impl CPU {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rlc(&mut self, byte: u8, direction: Direction) -> u8 {
|
||||||
|
let (mut rotated, carry) = rotate(byte, &direction);
|
||||||
|
if carry {
|
||||||
|
rotated += get_rotation_carry(&direction);
|
||||||
|
self.set_flag(FLAGS::C);
|
||||||
|
}
|
||||||
|
return rotated;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rl(&mut self, byte: u8, direction: Direction) -> u8 {
|
||||||
|
let old_carry = self.get_flag(FLAGS::C);
|
||||||
|
let (mut rotated, carry) = rotate(byte, &direction);
|
||||||
|
if old_carry > 0 {
|
||||||
|
rotated += get_rotation_carry(&direction);
|
||||||
|
}
|
||||||
|
if carry {
|
||||||
|
self.set_flag(FLAGS::C);
|
||||||
|
}
|
||||||
|
return rotated;
|
||||||
|
}
|
||||||
|
|
||||||
fn rst(&mut self, address: u16) {
|
fn rst(&mut self, address: u16) {
|
||||||
self.push(self.state.pc);
|
self.push(self.state.pc);
|
||||||
self.state.pc.as_u8s.left = 0x0;
|
self.state.pc.as_u8s.left = 0x0;
|
||||||
|
@ -1003,3 +1040,25 @@ fn get_bit(byte: u8, flag: u8) -> bool {
|
||||||
let got = byte & mask;
|
let got = byte & mask;
|
||||||
return got > 0x0;
|
return got > 0x0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rotate(byte: u8, direction: &Direction) -> (u8, bool) {
|
||||||
|
match direction {
|
||||||
|
Direction::Left => {
|
||||||
|
let carry = get_bit(byte, 7);
|
||||||
|
let r = byte << 1;
|
||||||
|
return (r, carry);
|
||||||
|
}
|
||||||
|
Direction::Right => {
|
||||||
|
let carry = get_bit(byte, 0);
|
||||||
|
let r = byte >> 1;
|
||||||
|
return (r, carry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_rotation_carry(direction: &Direction) -> u8 {
|
||||||
|
match direction {
|
||||||
|
Direction::Left => 0b1,
|
||||||
|
Direction::Right => 0b10000000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue