Skip to content

Commit

Permalink
Implemented RLA, RRA, CCF, LD HL, SP + i, RL, RR...
Browse files Browse the repository at this point in the history
... And fixed a few missing zero flag updates in CB opcodes
  • Loading branch information
velllu committed Sep 9, 2024
1 parent 464e91a commit 1296224
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 7 deletions.
47 changes: 42 additions & 5 deletions src/cpu/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
bus::Bus,
common::{merge_two_u8s_into_u16, split_u16_into_two_u8s},
common::{merge_two_u8s_into_u16, split_u16_into_two_u8s, Bit},
flags::Flags,
registers::Registers,
};
Expand Down Expand Up @@ -118,15 +118,34 @@ impl Cpu {
(1, 2)
}

// Instruction `RLA` - 00010111
// Shift register A left by one and set lower bit to carry flag
0x17 => {
let mut new_value = regs.a << 1;
new_value.set_bit(0, flags.carry);
regs.a = new_value;

(1, 1)
}

// Instruction `JR immediate data` - 00011000
// Convert immediate data to signed 8 bit number and add it to the pc
0x18 => {
let jump_amount = bus.next_one(regs) as i8;
add_i8_to_u16(&mut regs.pc, jump_amount);
regs.pc = add_i8_to_u16(regs.pc, jump_amount);

(2, 2)
}

// Instruction `RRA` - 00011111
// Rotate register A to the right by one and set register 7 to carry flag
0x1F => {
regs.a = regs.a.rotate_right(1);
regs.a.set_bit(7, flags.carry);

(1, 1)
}

// Instruction `JR condition, immediate data` - 001cc000
// Convert immediate data to signed 8 bit number and add it to the pc if
// condition applies
Expand All @@ -147,6 +166,14 @@ impl Cpu {
(1, 1)
}

// Instruction `CCF` - 00111111
// Flip carry flag
0x3F => {
flags.carry = !flags.carry;

(1, 1)
}

// Instruction Halt
// This is in the middle of the ld instructions, TODO: implement this fully
0x76 => (0, 1),
Expand Down Expand Up @@ -399,6 +426,16 @@ impl Cpu {
(1, 1)
}

// Instruction `LD HL, SP + immediate data` - 11111000
// Add SP to signed immediate data and copy the result to register HL
0xF8 => {
let immediate_data = bus.next_one(regs) as i8;
let new_value = add_i8_to_u16(regs.sp, immediate_data);
(regs.h, regs.l) = split_u16_into_two_u8s(new_value);

(2, 3)
}

// Instruction `LD register A, (immediate data)` - 11111010
// Load specified address into register A
0xFA => {
Expand Down Expand Up @@ -432,11 +469,11 @@ impl Cpu {
}
}

fn add_i8_to_u16(u16: &mut u16, i8: i8) {
*u16 = match i8 >= 0 {
fn add_i8_to_u16(u16: u16, i8: i8) -> u16 {
match i8 >= 0 {
true => u16.wrapping_add(i8 as u16),
false => u16.wrapping_sub(i8.unsigned_abs() as u16),
};
}
}

/// Cases:
Expand Down
49 changes: 47 additions & 2 deletions src/cpu/opcodes_cb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,56 @@ impl Cpu {
bus: &mut Bus,
) -> (Bytes, Cycles) {
match opcode {
// Instruction `RL r` - 00010rrr
// Rotate the contents of register r to the left and set bit 0 to carry flag
0x10..=0x17 => {
let register_r = regs.get_register(opcode, bus);
let mut new_value = register_r.rotate_left(1);
new_value.set_bit(0, flags.carry);

flags.zero = new_value == 0;
regs.set_register(opcode, new_value, bus);

(1, 1)
}

// Instruction `RR r` - 00011rrr
// Rotate the contents of register r to the right and set bit 7 to carry flag
0x18..=0x1F => {
let register_r = regs.get_register(opcode, bus);
let mut new_value = register_r.rotate_right(1);
new_value.set_bit(7, flags.carry);

flags.zero = new_value == 0;
regs.set_register(opcode, new_value, bus);

(1, 1)
}

// Instruction `SLA r` - 00100rrr
// Shift the contents of register r to the left and store bit 7 in carry flag
0x20..=0x27 => {
let register_r = regs.get_register(opcode, bus);
let new_value = register_r << 1;

flags.carry = register_r.get_bit(7);
flags.zero = new_value == 0;
regs.set_register(opcode, new_value, bus);

(1, 1)
}

// Instruction `SRA r` - 00100rrr
// Instruction `SRA r` - 00101rrr
// Shift the contents of register r to the right and store bit 0 in carry flag
// and mantain bit 7
0x28..=0x2F => {
let register_r = regs.get_register(opcode, bus);
let new_value = register_r >> 1;
let bit_7 = register_r.get_bit(7);
let mut new_value = register_r >> 1;
new_value.set_bit(7, bit_7);

flags.carry = register_r.get_bit(0);
flags.zero = new_value == 0;
regs.set_register(opcode, new_value, bus);

(1, 1)
Expand All @@ -43,6 +74,20 @@ impl Cpu {
let low = register_r << 4;
let new_value = high | low;

flags.zero = new_value == 0;
regs.set_register(opcode, new_value, bus);

(1, 1)
}

// Instruction `SRL r` - 00111rrr
// Shift the contents of register r to the right and store bit 0 in carry flag
0x38..=0x3F => {
let register_r = regs.get_register(opcode, bus);
let new_value = register_r >> 1;

flags.carry = register_r.get_bit(0);
flags.zero = new_value == 0;
regs.set_register(opcode, new_value, bus);

(1, 1)
Expand Down

0 comments on commit 1296224

Please sign in to comment.