mirror of
https://github.com/FranLMSP/rmg-001.git
synced 2024-11-23 10:12:11 +00:00
Functions and tests for some bitwise operations and getter/setter for flag register
This commit is contained in:
parent
b3e6baaa3f
commit
d37699f4a8
@ -1,3 +1,4 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
println!("TEST");
|
||||||
|
println!("{}", false as u8);
|
||||||
}
|
}
|
||||||
|
42
src/cpu.rs
42
src/cpu.rs
@ -1,3 +1,5 @@
|
|||||||
|
use crate::utils::{BitIndex, get_bit, set_bit};
|
||||||
|
|
||||||
pub enum Register {
|
pub enum Register {
|
||||||
A(u8), // Accumulator
|
A(u8), // Accumulator
|
||||||
F(u8), // Flags
|
F(u8), // Flags
|
||||||
@ -16,6 +18,13 @@ pub enum Register {
|
|||||||
PC(u16),
|
PC(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum FlagRegister {
|
||||||
|
Zero(bool), // Set when the result of a math operation is zero or if two values matches using the CP instruction
|
||||||
|
Substract(bool), // Set if a substraction was performed in the last math instruction
|
||||||
|
HalfCarry(bool), // Set if a carry ocurred from the lower nibble in the last math operation
|
||||||
|
Carry(bool), // Set if a carry was ocurrend from the last math operation or if register A is the smaller value when executing the CP instruction
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Registers {
|
pub struct Registers {
|
||||||
a: u8,
|
a: u8,
|
||||||
f: u8,
|
f: u8,
|
||||||
@ -30,6 +39,21 @@ pub struct Registers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Registers {
|
impl Registers {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
a: 0,
|
||||||
|
f: 0b11110000, // The first 4 lower bits are always set to 0
|
||||||
|
b: 0,
|
||||||
|
c: 0,
|
||||||
|
d: 0,
|
||||||
|
e: 0,
|
||||||
|
h: 0,
|
||||||
|
l: 0,
|
||||||
|
sp: 0,
|
||||||
|
pc: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self, register: Register) -> u16 {
|
pub fn get(&self, register: Register) -> u16 {
|
||||||
match register {
|
match register {
|
||||||
Register::A(_) => self.a as u16,
|
Register::A(_) => self.a as u16,
|
||||||
@ -66,6 +90,24 @@ impl Registers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_flag(&self, flag: FlagRegister) -> bool {
|
||||||
|
match flag {
|
||||||
|
FlagRegister::Zero(_) => get_bit(self.f, BitIndex::I7),
|
||||||
|
FlagRegister::Substract(_) => get_bit(self.f, BitIndex::I6),
|
||||||
|
FlagRegister::HalfCarry(_) => get_bit(self.f, BitIndex::I5),
|
||||||
|
FlagRegister::Carry(_) => get_bit(self.f, BitIndex::I4),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_flag(&mut self, flag: FlagRegister) {
|
||||||
|
match flag {
|
||||||
|
FlagRegister::Zero(val) => self.f = set_bit(self.f, val, BitIndex::I7),
|
||||||
|
FlagRegister::Substract(val) => self.f = set_bit(self.f, val, BitIndex::I6),
|
||||||
|
FlagRegister::HalfCarry(val) => self.f = set_bit(self.f, val, BitIndex::I5),
|
||||||
|
FlagRegister::Carry(val) => self.f = set_bit(self.f, val, BitIndex::I4),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_bc(&self) -> u16 {
|
fn get_bc(&self) -> u16 {
|
||||||
((self.b as u16) << 8) | (self.c as u16)
|
((self.b as u16) << 8) | (self.c as u16)
|
||||||
}
|
}
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
pub mod utils;
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
|
87
src/utils.rs
Normal file
87
src/utils.rs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
pub enum BitIndex {
|
||||||
|
I0,
|
||||||
|
I1,
|
||||||
|
I2,
|
||||||
|
I3,
|
||||||
|
I4,
|
||||||
|
I5,
|
||||||
|
I6,
|
||||||
|
I7,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_bit_index(index: BitIndex) -> u8 {
|
||||||
|
match index {
|
||||||
|
BitIndex::I0 => 0,
|
||||||
|
BitIndex::I1 => 1,
|
||||||
|
BitIndex::I2 => 2,
|
||||||
|
BitIndex::I3 => 3,
|
||||||
|
BitIndex::I4 => 4,
|
||||||
|
BitIndex::I5 => 5,
|
||||||
|
BitIndex::I6 => 6,
|
||||||
|
BitIndex::I7 => 7,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_bit(byte: u8, index: BitIndex) -> bool {
|
||||||
|
((byte >> get_bit_index(index)) & 0b00000001) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_bit(byte: u8, value: bool, index: BitIndex) -> u8 {
|
||||||
|
match value {
|
||||||
|
true => 0b00000001 << get_bit_index(index) | byte,
|
||||||
|
false => ((0b0000001 << get_bit_index(index)) ^ 0b11111111) & byte,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_set_bit() {
|
||||||
|
assert_eq!(set_bit(0b00000000, true, BitIndex::I0), 0b00000001);
|
||||||
|
assert_eq!(set_bit(0b00000000, true, BitIndex::I1), 0b00000010);
|
||||||
|
assert_eq!(set_bit(0b00000000, true, BitIndex::I2), 0b00000100);
|
||||||
|
assert_eq!(set_bit(0b00000000, true, BitIndex::I3), 0b00001000);
|
||||||
|
assert_eq!(set_bit(0b00000000, true, BitIndex::I4), 0b00010000);
|
||||||
|
assert_eq!(set_bit(0b00000000, true, BitIndex::I5), 0b00100000);
|
||||||
|
assert_eq!(set_bit(0b00000000, true, BitIndex::I6), 0b01000000);
|
||||||
|
assert_eq!(set_bit(0b00000000, true, BitIndex::I7), 0b10000000);
|
||||||
|
|
||||||
|
assert_eq!(set_bit(0b11111111, false, BitIndex::I0), 0b11111110);
|
||||||
|
assert_eq!(set_bit(0b11111111, false, BitIndex::I1), 0b11111101);
|
||||||
|
assert_eq!(set_bit(0b11111111, false, BitIndex::I2), 0b11111011);
|
||||||
|
assert_eq!(set_bit(0b11111111, false, BitIndex::I3), 0b11110111);
|
||||||
|
assert_eq!(set_bit(0b11111111, false, BitIndex::I4), 0b11101111);
|
||||||
|
assert_eq!(set_bit(0b11111111, false, BitIndex::I5), 0b11011111);
|
||||||
|
assert_eq!(set_bit(0b11111111, false, BitIndex::I6), 0b10111111);
|
||||||
|
assert_eq!(set_bit(0b11111111, false, BitIndex::I7), 0b01111111);
|
||||||
|
|
||||||
|
// Just a couple of random test
|
||||||
|
assert_eq!(set_bit(0b00000001, true, BitIndex::I0), 0b00000001);
|
||||||
|
assert_eq!(set_bit(0b11101111, true, BitIndex::I4), 0b11111111);
|
||||||
|
assert_eq!(set_bit(0b11111110, false, BitIndex::I0), 0b11111110);
|
||||||
|
assert_eq!(set_bit(0b00010000, false, BitIndex::I4), 0b00000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_bit() {
|
||||||
|
assert_eq!(get_bit(0b00000001, BitIndex::I0), true);
|
||||||
|
assert_eq!(get_bit(0b00000010, BitIndex::I1), true);
|
||||||
|
assert_eq!(get_bit(0b00000100, BitIndex::I2), true);
|
||||||
|
assert_eq!(get_bit(0b00001000, BitIndex::I3), true);
|
||||||
|
assert_eq!(get_bit(0b00010000, BitIndex::I4), true);
|
||||||
|
assert_eq!(get_bit(0b00100000, BitIndex::I5), true);
|
||||||
|
assert_eq!(get_bit(0b01000000, BitIndex::I6), true);
|
||||||
|
assert_eq!(get_bit(0b10000000, BitIndex::I7), true);
|
||||||
|
|
||||||
|
assert_eq!(get_bit(0b11111110, BitIndex::I0), false);
|
||||||
|
assert_eq!(get_bit(0b11111101, BitIndex::I1), false);
|
||||||
|
assert_eq!(get_bit(0b11111011, BitIndex::I2), false);
|
||||||
|
assert_eq!(get_bit(0b11110111, BitIndex::I3), false);
|
||||||
|
assert_eq!(get_bit(0b11101111, BitIndex::I4), false);
|
||||||
|
assert_eq!(get_bit(0b11011111, BitIndex::I5), false);
|
||||||
|
assert_eq!(get_bit(0b10111111, BitIndex::I6), false);
|
||||||
|
assert_eq!(get_bit(0b01111111, BitIndex::I7), false);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user