Implement Register methods, and stub ADD opcodes

This commit is contained in:
Rekai Musuka 2020-08-05 03:23:50 -05:00
parent 8b475cb4cf
commit a3cd9166ab
3 changed files with 169 additions and 23 deletions

View File

@ -1,10 +1,8 @@
#[derive(Debug, Copy, Clone)]
pub struct MemoryBus {
}
pub struct MemoryBus {}
impl MemoryBus {
pub fn read_byte(&self, _address: u16) {
pub fn read_byte(&self, _address: u16) -> u8 {
unimplemented!()
}

View File

@ -1,6 +1,6 @@
use super::bus::MemoryBus;
use std::ops::{Index, IndexMut};
use std::convert::From;
use std::ops::{Index, IndexMut};
#[derive(Debug, Copy, Clone)]
pub struct LR35902 {
@ -8,10 +8,81 @@ pub struct LR35902 {
registers: Registers,
sp: u16, // Stack Pointer
pc: u16, // Program Counter
flag: Flag, // Flag Register
ime: bool, // Interrupt Master Enable Flag
}
impl LR35902 {
pub fn fetch() -> u8 {
unimplemented!()
}
fn decode(opcode: u8) -> Instruction {
unimplemented!()
}
fn execute(&mut self, instruction: Instruction) {
match instruction {
Instruction::Add(target, source) => {
match target {
Argument::Register(reg) => {
let right = match source {
Argument::Register(other) => self.registers[other], // ADD A, r
Argument::ImmediateByte(byte) => byte, // ADD A, n
Argument::IndirectRegisterPair(pair) => {
// ADD A, (HL)
self.bus.read_byte(self.register_pair(pair))
}
_ => unreachable!(),
};
self.registers[reg] = self.add(self.registers[reg], right);
}
Argument::RegisterPair(pair) => {
let left = self.register_pair(pair);
if let Argument::RegisterPair(other) = source {
// ADD HL, rr
let sum = self.add_u16(left, self.register_pair(other));
self.set_register_pair(pair, sum);
} else if let Argument::ImmediateByte(byte) = source {
// ADD SP, dd
let byte = byte as i8;
let sum = self.add_u16_i8(left, byte);
self.set_register_pair(pair, sum);
}
}
_ => unreachable!(),
}
}
_ => unimplemented!("Unhandled Instruction {:?}", instruction),
}
}
fn add_u16_i8(&mut self, left: u16, right: i8) -> u16 {
unimplemented!()
}
fn add_u16(&mut self, left: u16, right: u16) -> u16 {
unimplemented!()
}
fn add(&mut self, left: u8, right: u8) -> u8 {
// Info on the Half-Carry flag
// https://robdor.com/2016/08/10/gameboy-emulator-half-carry-flag/
let (res, did_overflow) = left.overflowing_add(right);
self.registers.f = Flag {
z: res == 0,
n: false,
h: (((left & 0x0F) + (right & 0x0F)) & 0x10) == 0x10,
c: did_overflow,
}
.into();
res
}
}
#[derive(Debug, Copy, Clone)]
pub struct Flag {
z: bool, // Zero Flag
@ -29,7 +100,6 @@ impl From<u8> for Flag {
c: ((num >> 4) & 0x01) == 1,
}
}
}
impl From<Flag> for u8 {
@ -47,6 +117,7 @@ pub struct Registers {
e: u8,
h: u8,
l: u8,
f: u8,
}
impl Index<Register> for Registers {
@ -61,6 +132,7 @@ impl Index<Register> for Registers {
Register::E => &self.e,
Register::H => &self.h,
Register::L => &self.l,
Register::F => &self.f,
}
}
}
@ -75,6 +147,7 @@ impl IndexMut<Register> for Registers {
Register::E => &mut self.e,
Register::H => &mut self.h,
Register::L => &mut self.l,
Register::F => &mut self.f,
}
}
}
@ -88,4 +161,79 @@ pub enum Register {
E,
H,
L,
F,
}
#[derive(Debug, Copy, Clone)]
pub enum RegisterPair {
AF,
BC,
DE,
HL,
SP,
PC,
}
impl LR35902 {
pub fn register_pair(&self, pair: RegisterPair) -> u16 {
match pair {
RegisterPair::AF => {
(self.registers[Register::A] as u16) << 8 | self.registers[Register::F] as u16
}
RegisterPair::BC => {
(self.registers[Register::B] as u16) << 8 | self.registers[Register::C] as u16
}
RegisterPair::DE => {
(self.registers[Register::D] as u16) << 8 | self.registers[Register::E] as u16
}
RegisterPair::HL => {
(self.registers[Register::H] as u16) << 8 | self.registers[Register::L] as u16
}
RegisterPair::SP => self.sp,
RegisterPair::PC => self.pc,
}
}
pub fn set_register_pair(&mut self, pair: RegisterPair, value: u16) {
let high = (value >> 8) as u8;
let low = value as u8;
match pair {
RegisterPair::AF => {
self.registers[Register::A] = high;
self.registers[Register::F] = low;
}
RegisterPair::BC => {
self.registers[Register::B] = high;
self.registers[Register::C] = low;
}
RegisterPair::DE => {
self.registers[Register::D] = high;
self.registers[Register::E] = low;
}
RegisterPair::HL => {
self.registers[Register::H] = high;
self.registers[Register::L] = low;
}
RegisterPair::SP => self.sp = value,
RegisterPair::PC => self.pc = value,
}
}
}
#[derive(Debug, Copy, Clone)]
enum Argument {
Register(Register),
RegisterPair(RegisterPair),
IndirectRegisterPair(RegisterPair),
ImmediateByte(u8),
ImmediateWord(u16),
IndirectImmediateByte(u16),
}
#[derive(Debug, Copy, Clone)]
enum Instruction {
Add(Argument, Argument),
NOP,
STOP,
HALT,
}