gb-emu/src/processor/mod.rs

95 lines
1.9 KiB
Rust
Raw Normal View History

2023-01-31 10:05:36 +11:00
use std::mem::transmute;
2023-01-16 19:28:03 +11:00
2023-01-31 10:05:36 +11:00
use crate::{verbose_println, Memory, State};
2023-01-16 12:13:53 +11:00
2023-01-31 10:05:36 +11:00
mod instructions;
2023-01-22 09:39:45 +11:00
mod opcodes;
2023-01-22 09:18:07 +11:00
#[derive(PartialEq)]
2023-01-31 10:05:36 +11:00
pub(crate) enum FLAGS {
2023-01-22 13:09:31 +11:00
Zero = 7,
NSubtract = 6,
HalfCarry = 5,
Carry = 4,
2023-01-16 14:23:06 +11:00
}
2023-01-31 10:05:36 +11:00
pub(crate) enum Direction {
2023-01-18 13:14:22 +11:00
Left,
Right,
}
2023-01-16 12:13:53 +11:00
pub struct CPU {
pub memory: Memory,
pub state: State,
2023-01-18 12:45:56 +11:00
pub last_instruction: u8,
pub last_instruction_addr: u16,
2023-01-16 12:13:53 +11:00
}
impl CPU {
2023-01-17 09:09:53 +11:00
pub fn exec_next(&mut self) {
2023-01-18 12:45:56 +11:00
unsafe { self.last_instruction_addr = self.state.pc.as_u16 };
2023-01-16 12:13:53 +11:00
let opcode = self.next_opcode();
2023-01-18 12:45:56 +11:00
self.last_instruction = opcode;
2023-01-22 12:13:02 +11:00
verbose_println!(
2023-01-22 09:32:19 +11:00
"exec {:#4X} from pc: {:#X}",
2023-01-22 12:13:02 +11:00
opcode,
self.last_instruction_addr
2023-01-22 09:32:19 +11:00
);
2023-01-22 09:39:45 +11:00
self.run_opcode(opcode);
2023-01-16 12:13:53 +11:00
}
fn next_opcode(&mut self) -> u8 {
unsafe {
let opcode = self.memory.get(self.state.pc.as_u16);
self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(0x1);
2023-01-16 12:13:53 +11:00
return opcode;
};
}
}
2023-01-17 09:09:53 +11:00
fn as_signed(unsigned: u8) -> i8 {
unsafe {
return transmute(unsigned);
}
}
2023-01-18 12:45:56 +11:00
fn get_bit(byte: u8, flag: u8) -> bool {
let mask = 1 << flag;
let got = byte & mask;
return got > 0x0;
}
2023-01-18 13:14:22 +11:00
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,
}
}
2023-01-18 14:43:24 +11:00
fn swap_nibbles(byte: u8) -> u8 {
(byte & 0x0F) << 4 | (byte & 0xF0) >> 4
}
fn res(byte: u8, bit: u8) -> u8 {
byte & !(1 << bit)
}
fn set(byte: u8, bit: u8) -> u8 {
byte | (1 << bit)
}