diff --git a/src/bin/main.rs b/src/bin/main.rs index 6154dee..00dc4f7 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -28,13 +28,27 @@ extern crate emu6502; use emu6502::machine; +use emu6502::address::Address; fn main() { let mut machine = machine::Machine::new(); + + // "Load" a program + machine.memory.set_byte(&Address(0), 0x69); // ADC immediate opcode + machine.memory.set_byte(&Address(1), 0x07); // Immediate operand + machine.memory.set_byte(&Address(2), 0x69); // ADC immediate opcode + machine.memory.set_byte(&Address(3), 0x08); // ADC immediate opcode + + // Obviously this will run the full program, just + // executing a finite num of instructions for simplicity + // right now. + for _ in range(0u, 2u) { + let raw_instruction = machine.fetch_instruction(); + let instruction = machine.decode_instruction(raw_instruction); + machine.execute_instruction(instruction); + } - println!("A: {}", machine.registers.accumulator); - println!("add_with_carry(1)"); - machine.add_with_carry(1); - println!("A: {}", machine.registers.accumulator); + println!("{}", machine); + } diff --git a/src/instruction.rs b/src/instruction.rs index 44025df..fac9cd4 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -48,7 +48,9 @@ pub enum Instruction // NV BDIZC A X Y S PC M // // | outputs | inputs -{ ADC // ADd with Carry................ | NV ...ZC A = A + M + C +{ + ADC(i8) // ADd with Carry............ | NV ...ZC A = A + M + C + , AND // logical AND (bitwise)......... | N. ...Z. A = A && M , ASL // Arithmetic Shift Left......... | N. ...ZC A = M << 1 , BCC // Branch if Carry Clear......... | .. ..... PC = !C diff --git a/src/machine.rs b/src/machine.rs index 5ae4086..5886425 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -25,6 +25,10 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +use address::AddressDiff; +use std::fmt; +use instruction::Instruction; +use instruction::{ADC, NOP}; use memory::Memory; use registers::{ Registers, Status, StatusArgs }; use registers::{ ps_negative, ps_overflow, ps_zero, ps_carry }; @@ -45,6 +49,35 @@ impl Machine { pub fn reset(&mut self) { *self = Machine::new(); } + + pub fn fetch_instruction(&mut self) -> i8 { + let instr = self.memory.get_byte(&self.registers.program_counter); + + // Will need smarter logic to fetch the correct number of bytes + // for instruction + self.registers.program_counter = self.registers.program_counter + AddressDiff(1); + instr as i8 + } + + pub fn decode_instruction(&mut self, raw_instruction: i8) -> Instruction { + match raw_instruction { + 0x69 => ADC(self.fetch_instruction()), + _ => NOP + } + } + + pub fn execute_instruction(&mut self, instruction: Instruction) { + match instruction { + ADC(immediate) => { + println!("executing add with carry"); + self.add_with_carry(immediate); + }, + NOP => { + println!("nop instr"); + } + _ => println!("attempting to execute unimplemented instruction") + }; + } // TODO akeeton: Implement binary-coded decimal. pub fn add_with_carry(&mut self, value: i8) { @@ -76,6 +109,12 @@ impl Machine { } } +impl fmt::Show for Machine { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Machine Dump:\n\nAccumulator: {}", self.registers.accumulator) + } +} + #[test] fn add_with_carry_test() {