diff --git a/src/bus.rs b/src/bus.rs deleted file mode 100644 index b182a5f..0000000 --- a/src/bus.rs +++ /dev/null @@ -1,20 +0,0 @@ -#[derive(Debug, Copy, Clone)] -pub struct MemoryBus {} - -impl MemoryBus { - pub fn read_byte(&self, _address: u16) -> u8 { - unimplemented!() - } - - pub fn write_byte(&mut self, _address: u16) { - unimplemented!() - } - - pub fn read_word(&self, _address: u16) -> u16 { - unimplemented!() - } - - pub fn write_word(&mut self, __address: u16) { - unimplemented!() - } -} diff --git a/src/cpu.rs b/src/cpu.rs deleted file mode 100644 index ca49eca..0000000 --- a/src/cpu.rs +++ /dev/null @@ -1,184 +0,0 @@ -use super::bus::MemoryBus; -use super::Instruction; -use std::convert::From; - -#[derive(Debug, Copy, Clone)] -pub struct Cpu { - bus: MemoryBus, - reg: Registers, - ime: bool, - pc: u16, - sp: u16, -} - -impl Cpu { - pub fn run(&mut self) -> ! { - loop { - let opcode = self.fetch(); - let instruction = self.decode(opcode); - self.execute(instruction); - } - } - - fn fetch(&self) -> u8 { - unimplemented!() - } - - fn decode(&self, opcode: u8) -> Instruction { - unimplemented!() - } - - fn execute(&mut self, instruction: Instruction) { - unimplemented!() - } -} - -impl Cpu { - pub fn read_byte(&self, address: u16) -> u8 { - self.bus.read_byte(address) - } - - pub fn write_byte(&mut self, address: u16) { - self.bus.write_byte(address) - } - - pub fn read_word(&self, address: u16) -> u16 { - self.bus.read_word(address) - } - - pub fn write_word(&mut self, address: u16) { - self.bus.write_word(address) - } -} - -impl Cpu { - pub fn register_pair(&self, pair: RegisterPair) -> u16 { - match pair { - RegisterPair::AF => { - (self.register(Register::A) as u16) << 8 | self.register(Register::Flag) as u16 - } - RegisterPair::BC => { - (self.register(Register::B) as u16) << 8 | self.register(Register::C) as u16 - } - RegisterPair::DE => { - (self.register(Register::D) as u16) << 8 | self.register(Register::E) as u16 - } - RegisterPair::HL => { - (self.register(Register::H) as u16) << 8 | self.register(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.set_register(Register::A, high); - self.set_register(Register::Flag, low); - } - RegisterPair::BC => { - self.set_register(Register::B, high); - self.set_register(Register::C, low); - } - RegisterPair::DE => { - self.set_register(Register::D, high); - self.set_register(Register::E, low); - } - RegisterPair::HL => { - self.set_register(Register::H, high); - self.set_register(Register::L, low); - } - RegisterPair::SP => self.sp = value, - RegisterPair::PC => self.pc = value, - } - } - - pub fn register(&self, reg: Register) -> u8 { - match reg { - Register::A => self.reg.a, - Register::B => self.reg.b, - Register::C => self.reg.c, - Register::D => self.reg.d, - Register::E => self.reg.e, - Register::H => self.reg.h, - Register::L => self.reg.l, - Register::Flag => self.reg.f.into(), - } - } - - pub fn set_register(&mut self, reg: Register, value: u8) { - match reg { - Register::A => self.reg.a = value, - Register::B => self.reg.b = value, - Register::C => self.reg.c = value, - Register::D => self.reg.d = value, - Register::E => self.reg.e = value, - Register::H => self.reg.h = value, - Register::L => self.reg.l = value, - Register::Flag => self.reg.f = value.into(), - } - } -} - -#[derive(Debug, Copy, Clone)] -struct Registers { - a: u8, - b: u8, - c: u8, - d: u8, - e: u8, - h: u8, - l: u8, - f: Flag, -} - -#[derive(Debug, Copy, Clone)] -pub enum RegisterPair { - AF, - BC, - DE, - HL, - SP, - PC, -} - -#[derive(Debug, Copy, Clone)] -pub enum Register { - A, - B, - C, - D, - E, - H, - L, - Flag, -} - -#[derive(Debug, Copy, Clone)] -struct Flag { - z: bool, // Zero Flag - n: bool, // Negative Flag - h: bool, // Half-Carry Flag - c: bool, // Carry Flag -} - -impl From for Flag { - fn from(flag: u8) -> Self { - Self { - z: (flag >> 7) == 1, - n: ((flag >> 6) & 0x01) == 1, - h: ((flag >> 5) & 0x01) == 1, - c: ((flag >> 4) & 0x01) == 1, - } - } -} - -impl From for u8 { - fn from(flag: Flag) -> Self { - (flag.z as u8) << 7 | (flag.n as u8) << 6 | (flag.h as u8) << 5 | (flag.c as u8) << 4 - } -} diff --git a/src/instruction.rs b/src/instruction.rs deleted file mode 100644 index 8d77ad7..0000000 --- a/src/instruction.rs +++ /dev/null @@ -1,262 +0,0 @@ -use super::cpu::Cpu; -use super::cpu::Register; -use super::cpu::RegisterPair; - -pub enum Instruction { - NOP, - LD(Argument, Argument), - STOP, - JP(Condition, Argument), - JR(Condition, i8), - ADD(Argument, Argument), - LDD(Argument, Argument), - LDI(Argument, Argument), - INC(AllRegisters), - DEC(AllRegisters), - RLCA, - RRCA, - RLA, - RRA, - DAA, - CPL, - SCF, - CCF, - HALT, - ADC(Argument, Argument), - SUB, - SBC(Argument, Argument), - AND, - XOR, - OR, - CP, - RET(Condition), -} - -pub enum AllRegisters { - U8(Register), - U16(RegisterPair), - IndirectHL, -} - -pub enum Argument { - ImmediateByte(u8), - ImmediateWord(u16), - IndirectImmediateByte(u16), - Register(Register), - RegisterPair(RegisterPair), - IndirectRegister(RegisterPair), -} - -impl Instruction { - pub fn from_byte(cpu: &Cpu, byte: u8) -> Instruction { - if byte == 0xCB { - Self::from_prefixed_byte(cpu, byte) - } else { - Self::from_unprefixed_byte(cpu, byte) - } - } - - pub fn from_unprefixed_byte(cpu: &Cpu, byte: u8) -> Instruction { - // https://gb-archive.github.io/salvage/decoding_gbz80_opcodes/Decoding%20Gamboy%20Z80%20Opcodes.html - let x = (byte >> 6) & 0b00000011; - let y = (byte >> 3) & 0b00000111; - let z = byte & 0b00000111; - let p = y >> 1; - let q = y >> 3 & 0b00000001; - - let n = cpu.read_byte(cpu.register_pair(RegisterPair::PC) + 1); - let nn = cpu.read_word(cpu.register_pair(RegisterPair::PC) + 1); - - match (x, z, q, y, p) { - (0, 0, _, 0, _) => Instruction::NOP, // NOP - (0, 0, _, 1, _) => Instruction::LD( - // LD (nn), SP - Argument::IndirectImmediateByte(nn), - Argument::RegisterPair(RegisterPair::SP), - ), - (0, 0, _, 2, _) => Instruction::STOP, // STOP - (0, 0, _, 3, _) => Instruction::JR(Condition::Always, n as i8), // JR d - (0, 0, _, 4..=7, _) => Instruction::JR(Self::table_cc(y - 4), n as i8), // JR cc[y - 4], d - (0, 1, 0, _, p) => Instruction::LD( - // LD rp[p], nn - Argument::RegisterPair(Self::table_rp(p)), - Argument::IndirectImmediateByte(nn), - ), - (0, 1, 1, _, p) => { - // ADD HL, rp[p] - Instruction::ADD( - Argument::RegisterPair(RegisterPair::HL), - Argument::RegisterPair(Self::table_rp(p)), - ) - } - (0, 2, 0, _, 0) => Instruction::LD( - // LD (BC), A - Argument::IndirectRegister(RegisterPair::BC), - Argument::Register(Register::A), - ), - (0, 2, 0, _, 1) => Instruction::LD( - // LD (DE), A - Argument::IndirectRegister(RegisterPair::DE), - Argument::Register(Register::A), - ), - (0, 2, 1, _, 0) => Instruction::LD( - // LD A, (BC) - Argument::Register(Register::A), - Argument::IndirectRegister(RegisterPair::BC), - ), - (0, 2, 1, _, 1) => Instruction::LD( - // LD A, (DE) - Argument::Register(Register::A), - Argument::IndirectRegister(RegisterPair::DE), - ), - (0, 2, 0, _, 2) => Instruction::LDI( - // LD (HL+), A - Argument::IndirectRegister(RegisterPair::HL), - Argument::Register(Register::A), - ), - (0, 2, 0, _, 3) => Instruction::LDD( - // LD (HL-), A - Argument::IndirectRegister(RegisterPair::HL), - Argument::Register(Register::A), - ), - (0, 2, 1, _, 2) => Instruction::LDI( - // LD A, (HL+) - Argument::Register(Register::A), - Argument::IndirectRegister(RegisterPair::HL), - ), - (0, 2, 1, _, 3) => Instruction::LDD( - // LD A, (HL-) - Argument::Register(Register::A), - Argument::IndirectRegister(RegisterPair::HL), - ), - (0, 3, 0, _, p) => Instruction::INC(AllRegisters::U16(Self::table_rp(p))), // INC rp[p] - (0, 3, 1, _, p) => Instruction::DEC(AllRegisters::U16(Self::table_rp(p))), // DEC rp[p] - (0, 4, _, y, _) => Instruction::INC(Self::table_r(y)), // INC r[y] - (0, 5, _, y, _) => Instruction::DEC(Self::table_r(y)), // DEC r[y] - (0, 6, _, y, _) => Instruction::LD( - // LD r[y], n - Self::arg_table_r(y), - Argument::ImmediateByte(n), - ), - (0, 7, _, 0, _) => Instruction::RLCA, - (0, 7, _, 1, _) => Instruction::RRCA, - (0, 7, _, 2, _) => Instruction::RLA, - (0, 7, _, 3, _) => Instruction::RRA, - (0, 7, _, 4, _) => Instruction::DAA, - (0, 7, _, 5, _) => Instruction::CPL, - (0, 7, _, 6, _) => Instruction::SCF, - (0, 7, _, 7, _) => Instruction::CCF, - (1, 6, _, 6, _) => Instruction::HALT, - (1, z, _, y, _) => Instruction::LD( - // LD r[y], r[z] - Self::arg_table_r(y), - Self::arg_table_r(z), - ), - (2, z, _, y, _) => Self::table_alu(y, z), - (3, 0, _, 0..=3, _) => Instruction::RET( - // RET cc[y] - Self::table_cc(y), - ), - (3, 0, _, 4, _) => Instruction::LD( - // LD (0xFF00 + n), A - Argument::IndirectImmediateByte(0xFF00 + (n as u16)), - Argument::Register(Register::A), - ), - (3, 0, _, 5, _) => Instruction::ADD( - Argument::RegisterPair(RegisterPair::SP), - Argument::ImmediateByte(n), - ), - _ => unreachable!(), - } - } - - pub fn from_prefixed_byte(cpu: &Cpu, byte: u8) -> Instruction { - unimplemented!() - } - - fn arg_table_r(index: u8) -> Argument { - match Self::table_r(index) { - AllRegisters::U8(register) => Argument::Register(register), - AllRegisters::IndirectHL => Argument::IndirectRegister(RegisterPair::HL), - _ => unreachable!(), - } - } - - fn table_r(index: u8) -> AllRegisters { - match index { - 0 => AllRegisters::U8(Register::B), - 1 => AllRegisters::U8(Register::C), - 2 => AllRegisters::U8(Register::D), - 3 => AllRegisters::U8(Register::E), - 4 => AllRegisters::U8(Register::H), - 5 => AllRegisters::U8(Register::L), - 6 => AllRegisters::IndirectHL, - 7 => AllRegisters::U8(Register::A), - _ => unreachable!(), - } - } - - fn table_rp2(index: u8) -> RegisterPair { - match index { - 0 => RegisterPair::BC, - 1 => RegisterPair::DE, - 2 => RegisterPair::HL, - 3 => RegisterPair::AF, - _ => unreachable!(), - } - } - - fn table_rp(index: u8) -> RegisterPair { - match index { - 0 => RegisterPair::BC, - 1 => RegisterPair::DE, - 2 => RegisterPair::HL, - 3 => RegisterPair::SP, - _ => unreachable!(), - } - } - - fn table_cc(index: u8) -> Condition { - match index { - 0 => Condition::NotZero, - 1 => Condition::Zero, - 2 => Condition::NotCarry, - 3 => Condition::Carry, - _ => unreachable!(), - } - } - - fn table_alu(fn_index: u8, reg_index: u8) -> Instruction { - match fn_index { - 0 => Instruction::ADD( - // ADD A, r[z] - Argument::Register(Register::A), - Self::arg_table_r(reg_index), - ), - 1 => Instruction::ADC( - // ADC A, r[z] - Argument::Register(Register::A), - Self::arg_table_r(reg_index), - ), - 2 => Instruction::SUB, - 3 => Instruction::SBC( - // SBC A, r[z] - Argument::Register(Register::A), - Self::arg_table_r(reg_index), - ), - 4 => Instruction::AND, - 5 => Instruction::XOR, - 6 => Instruction::OR, - 7 => Instruction::CP, - _ => unreachable!(), - } - } -} - -pub enum Condition { - NotZero, - Zero, - NotCarry, - Carry, - Always, -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index aa4a768..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -use instruction::Instruction; - -mod bus; -mod cpu; -mod instruction; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -}