From b546c62946e05ff01bfef6d9f78e761b7ecc75af Mon Sep 17 00:00:00 2001 From: Andrew Keeton Date: Sun, 28 Sep 2014 17:58:02 -0400 Subject: [PATCH] Add a BitFlag enum for the Status registers, replacing u8s. --- 6502emu/src/address.rs | 4 +++ 6502emu/src/machine.rs | 23 +++++++++-------- 6502emu/src/main.rs | 5 ++-- 6502emu/src/memory.rs | 8 ++---- 6502emu/src/registers.rs | 54 ++++++++++++++++++++-------------------- 6502emu/src/util.rs | 48 +++++++++++++++++++++++++++++++++++ 6 files changed, 97 insertions(+), 45 deletions(-) create mode 100644 6502emu/src/util.rs diff --git a/6502emu/src/address.rs b/6502emu/src/address.rs index a157413..d2c2895 100644 --- a/6502emu/src/address.rs +++ b/6502emu/src/address.rs @@ -35,6 +35,10 @@ impl Address { } } + pub fn to_uint(&self) -> uint { + self.to_u16() as uint + } + pub fn get_page_number(&self) -> u8 { (self.to_u16() & 0xff00 >> 8) as u8 } diff --git a/6502emu/src/machine.rs b/6502emu/src/machine.rs index 7048942..da2a6df 100644 --- a/6502emu/src/machine.rs +++ b/6502emu/src/machine.rs @@ -25,8 +25,9 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -use registers::Registers; +use util::BitFlag; use memory::Memory; +use registers::Registers; pub struct Machine { pub registers: Registers, @@ -49,15 +50,17 @@ impl Machine { let a_new_full: int = a + c + value as int; let a_new: i8 = a_new_full as i8; + let did_carry = a_new_full != a_new as int; + let is_zero = a_new == 0; + let is_negative = a_new < 0; + let did_overflow = + (a < 0 && value < 0 && a_new >= 0) + || (a > 0 && value > 0 && a_new <= 0); + self.registers.accumulator = a_new; - self.registers.status.carry = if a_new_full == a_new as int { 0 } else { 1 }; - self.registers.status.zero = if a_new == 0 { 1 } else { 0 }; - self.registers.status.sign = if a_new < 0 { 1 } else { 0 }; - self.registers.status.overflow = - if (a < 0 && value < 0 && a_new >= 0) - || (a > 0 && value > 0 && a_new <= 0) - { 1 } - else - { 0 } + self.registers.status.carry = BitFlag::new(did_carry); + self.registers.status.zero = BitFlag::new(is_zero); + self.registers.status.sign = BitFlag::new(is_negative); + self.registers.status.overflow = BitFlag::new(did_overflow); } } \ No newline at end of file diff --git a/6502emu/src/main.rs b/6502emu/src/main.rs index 01f1b2a..be0181e 100644 --- a/6502emu/src/main.rs +++ b/6502emu/src/main.rs @@ -25,10 +25,11 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -mod machine; -mod registers; mod address; +mod machine; mod memory; +mod registers; +mod util; fn main() { let mut machine = machine::Machine::new(); diff --git a/6502emu/src/memory.rs b/6502emu/src/memory.rs index bc057fe..7c76258 100644 --- a/6502emu/src/memory.rs +++ b/6502emu/src/memory.rs @@ -45,22 +45,18 @@ impl Memory { } pub fn get_byte(&self, address: &Address) -> u8 { - self.bytes[Memory::address_to_byte_offset(address)] + self.bytes[address.to_uint()] } // Sets the byte at the given address to the given value and returns the // previous value at the address. pub fn set_byte(&mut self, address: &Address, value: u8) -> u8 { let old_value = self.get_byte(address); - self.bytes[Memory::address_to_byte_offset(address)] = value; + self.bytes[address.to_uint()] = value; return old_value; } - fn address_to_byte_offset(address: &Address) -> uint { - (STACK_ADDRESS_BEGIN.to_u16() - STACK_ADDRESS_END.to_u16()) as uint - } - fn is_stack_address(address: &Address) -> bool { STACK_ADDRESS_BEGIN <= *address && *address <= STACK_ADDRESS_END } diff --git a/6502emu/src/registers.rs b/6502emu/src/registers.rs index 006eb6b..c9b5e39 100644 --- a/6502emu/src/registers.rs +++ b/6502emu/src/registers.rs @@ -25,43 +25,43 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -use memory; +use memory::STACK_ADDRESS_END; +use util::{ BitFlag, Off, On }; -// Each status flag should be 0 or 1. pub struct Status { - pub carry: u8, - pub zero: u8, - pub interrupt: u8, - pub decimal_mode: u8, - pub brk: u8, - pub unused: u8, - pub overflow: u8, - pub sign: u8 + pub carry: BitFlag, + pub zero: BitFlag, + pub interrupt: BitFlag, + pub decimal_mode: BitFlag, + pub brk: BitFlag, + pub unused: BitFlag, + pub overflow: BitFlag, + pub sign: BitFlag } impl Status { pub fn to_byte(&self) -> u8 { - self.carry << 0 - | self.zero << 1 - | self.interrupt << 2 - | self.decimal_mode << 3 - | self.brk << 4 - | self.unused << 5 - | self.overflow << 6 - | self.sign << 7 + self.carry.to_bit() << 0 + | self.zero.to_bit() << 1 + | self.interrupt.to_bit() << 2 + | self.decimal_mode.to_bit() << 3 + | self.brk.to_bit() << 4 + | self.unused.to_bit() << 5 + | self.overflow.to_bit() << 6 + | self.sign.to_bit() << 7 } pub fn new() -> Status { // TODO akeeton: Revisit these defaults. Status { - carry: 0, - zero: 0, - interrupt: 0, - decimal_mode: 0, - brk: 0, - unused: 1, - overflow: 0, - sign: 0 + carry: Off, + zero: Off, + interrupt: Off, + decimal_mode: Off, + brk: Off, + unused: On, + overflow: Off, + sign: Off } } } @@ -82,7 +82,7 @@ impl Registers { accumulator: 0, index_x: 0, index_y: 0, - stack_pointer: memory::STACK_ADDRESS_END.get_offset(), + stack_pointer: STACK_ADDRESS_END.get_offset(), program_counter: 0, status: Status::new() } diff --git a/6502emu/src/util.rs b/6502emu/src/util.rs new file mode 100644 index 0000000..d07c1ba --- /dev/null +++ b/6502emu/src/util.rs @@ -0,0 +1,48 @@ +// Copyright (C) 2014 The 6502-rs Developers +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the names of the copyright holders nor the names of any +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +pub enum BitFlag { + Off, + On +} + +impl BitFlag { + pub fn new(is_set: bool) -> BitFlag { + if is_set { + On + } else { + Off + } + } + + pub fn to_bit(&self) -> u8 { + match *self { + Off => 0, + On => 1 + } + } +} \ No newline at end of file