mirror of
https://github.com/mre/mos6502.git
synced 2024-11-30 20:51:21 +00:00
Fix breaking changes.
This commit is contained in:
parent
bd30f8c6cc
commit
5e4dc965bf
@ -38,3 +38,6 @@ name = "emu6502"
|
|||||||
# This will look in src/bin/emu6502.rs
|
# This will look in src/bin/emu6502.rs
|
||||||
name = "emu6502"
|
name = "emu6502"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log = "0.1.0"
|
||||||
|
|
||||||
|
@ -26,17 +26,20 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
use std::num::Int;
|
use std::num::Int;
|
||||||
|
use std::ops::Add;
|
||||||
|
|
||||||
// The idea here is that it doesn't make sense to add two addresses, but it
|
// The idea here is that it doesn't make sense to add two addresses, but it
|
||||||
// does make sense to add an address and an "address-difference". (If this
|
// does make sense to add an address and an "address-difference". (If this
|
||||||
// is too annoying to work with we should let it go.)
|
// is too annoying to work with we should let it go.)
|
||||||
#[deriving(Copy, PartialEq, Eq, PartialOrd, Ord, Show)]
|
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Show)]
|
||||||
pub struct AddressDiff(pub i32);
|
pub struct AddressDiff(pub i32);
|
||||||
|
|
||||||
#[deriving(Copy, PartialEq, Eq, PartialOrd, Ord, Show)]
|
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Show)]
|
||||||
pub struct Address(pub u16);
|
pub struct Address(pub u16);
|
||||||
|
|
||||||
impl Add<AddressDiff, Address> for Address {
|
impl Add<AddressDiff> for Address {
|
||||||
|
type Output = Address;
|
||||||
|
|
||||||
fn add(self, AddressDiff(rhs): AddressDiff) -> Address {
|
fn add(self, AddressDiff(rhs): AddressDiff) -> Address {
|
||||||
let Address(lhs) = self;
|
let Address(lhs) = self;
|
||||||
|
|
||||||
@ -45,17 +48,21 @@ impl Add<AddressDiff, Address> for Address {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<AddressDiff, AddressDiff> for AddressDiff {
|
impl Add for AddressDiff {
|
||||||
|
type Output = AddressDiff;
|
||||||
|
|
||||||
fn add(self, AddressDiff(rhs): AddressDiff) -> AddressDiff {
|
fn add(self, AddressDiff(rhs): AddressDiff) -> AddressDiff {
|
||||||
let AddressDiff(lhs) = self;
|
let AddressDiff(lhs) = self;
|
||||||
AddressDiff(lhs + rhs)
|
AddressDiff(lhs + rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct CheckedAddressDiff(u16);
|
pub struct CheckedAddressDiff(u16);
|
||||||
|
|
||||||
impl Add<CheckedAddressDiff, Address> for Address {
|
impl Add<CheckedAddressDiff> for Address {
|
||||||
|
type Output = Address;
|
||||||
|
|
||||||
fn add(self, CheckedAddressDiff(rhs): CheckedAddressDiff) -> Address {
|
fn add(self, CheckedAddressDiff(rhs): CheckedAddressDiff) -> Address {
|
||||||
let Address(lhs) = self;
|
let Address(lhs) = self;
|
||||||
|
|
||||||
@ -74,8 +81,8 @@ impl Address {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_uint(&self) -> uint {
|
pub fn to_usize(&self) -> usize {
|
||||||
self.to_u16() as uint
|
self.to_u16() as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_page_number(&self) -> u8 {
|
pub fn get_page_number(&self) -> u8 {
|
||||||
|
@ -42,7 +42,7 @@ fn main() {
|
|||||||
// JAM: FIXME: What's the syntax for specifying the array element type,
|
// JAM: FIXME: What's the syntax for specifying the array element type,
|
||||||
// but not the length? (For a fixed-size array)
|
// but not the length? (For a fixed-size array)
|
||||||
|
|
||||||
let zero_page_data: [u8, ..17] = [
|
let zero_page_data: [u8; 17] = [
|
||||||
// ZeroPage data start
|
// ZeroPage data start
|
||||||
0x00,
|
0x00,
|
||||||
0x02, // ADC ZeroPage target
|
0x02, // ADC ZeroPage target
|
||||||
@ -63,7 +63,7 @@ fn main() {
|
|||||||
0x80, // ADC IndirectIndexedY address
|
0x80, // ADC IndirectIndexedY address
|
||||||
];
|
];
|
||||||
|
|
||||||
let program: [u8, ..33] = [
|
let program: [u8; 33] = [
|
||||||
// Code start
|
// Code start
|
||||||
0xA9, // LDA Immediate
|
0xA9, // LDA Immediate
|
||||||
0x01, // Immediate operand
|
0x01, // Immediate operand
|
||||||
@ -115,7 +115,7 @@ fn main() {
|
|||||||
0xFF, // Something invalid -- the end!
|
0xFF, // Something invalid -- the end!
|
||||||
];
|
];
|
||||||
|
|
||||||
let data: [u8, ..25] = [
|
let data: [u8; 25] = [
|
||||||
0x00,
|
0x00,
|
||||||
0x09, // ADC Absolute target
|
0x09, // ADC Absolute target
|
||||||
0x00,
|
0x00,
|
||||||
@ -151,6 +151,6 @@ fn main() {
|
|||||||
|
|
||||||
machine.run();
|
machine.run();
|
||||||
|
|
||||||
println!("{}", machine);
|
println!("{:?}", machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ use machine::Machine;
|
|||||||
// PC | program counter
|
// PC | program counter
|
||||||
//
|
//
|
||||||
|
|
||||||
#[deriving(Copy, Show, PartialEq, Eq)]
|
#[derive(Copy, Show, PartialEq, Eq)]
|
||||||
pub enum Instruction
|
pub enum Instruction
|
||||||
// i/o vars should be listed as follows:
|
// i/o vars should be listed as follows:
|
||||||
// NV BDIZC A X Y S PC M
|
// NV BDIZC A X Y S PC M
|
||||||
@ -113,7 +113,7 @@ pub enum Instruction
|
|||||||
, TYA // Transfer Y to Accumulator..... | N. ...Z. A = Y
|
, TYA // Transfer Y to Accumulator..... | N. ...Z. A = Y
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Copy)]
|
#[derive(Copy)]
|
||||||
pub enum OpInput {
|
pub enum OpInput {
|
||||||
UseImplied,
|
UseImplied,
|
||||||
UseImmediate(u8),
|
UseImmediate(u8),
|
||||||
@ -121,7 +121,7 @@ pub enum OpInput {
|
|||||||
UseAddress(Address),
|
UseAddress(Address),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Copy)]
|
#[derive(Copy)]
|
||||||
pub enum AddressingMode
|
pub enum AddressingMode
|
||||||
// length
|
// length
|
||||||
{ Accumulator // 1 LSR A work directly on accumulator
|
{ Accumulator // 1 LSR A work directly on accumulator
|
||||||
@ -144,7 +144,7 @@ pub enum AddressingMode
|
|||||||
fn arr_to_addr(arr: &[u8]) -> Address {
|
fn arr_to_addr(arr: &[u8]) -> Address {
|
||||||
debug_assert!(arr.len() == 2);
|
debug_assert!(arr.len() == 2);
|
||||||
|
|
||||||
let x = (arr[0] as u16) + (arr[1] as u16 << 8u);
|
let x = (arr[0] as u16) + ((arr[1] as u16) << 8us);
|
||||||
Address(x)
|
Address(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ impl AddressingMode {
|
|||||||
pub fn process(self, machine: &Machine, arr: &[u8]) -> OpInput {
|
pub fn process(self, machine: &Machine, arr: &[u8]) -> OpInput {
|
||||||
|
|
||||||
debug_assert!({let AddressDiff(x) = self.extra_bytes();
|
debug_assert!({let AddressDiff(x) = self.extra_bytes();
|
||||||
arr.len() == x as uint});
|
arr.len() == x as usize});
|
||||||
|
|
||||||
let x = machine.registers.index_x as u8;
|
let x = machine.registers.index_x as u8;
|
||||||
let y = machine.registers.index_y as u8;
|
let y = machine.registers.index_y as u8;
|
||||||
@ -258,7 +258,7 @@ impl AddressingMode {
|
|||||||
|
|
||||||
pub type DecodedInstr = (Instruction, OpInput);
|
pub type DecodedInstr = (Instruction, OpInput);
|
||||||
|
|
||||||
pub static OPCODES: [Option<(Instruction, AddressingMode)>, ..256] = [
|
pub static OPCODES: [Option<(Instruction, AddressingMode)>; 256] = [
|
||||||
/*0x00*/ Some((Instruction::BRK, AddressingMode::Implied)),
|
/*0x00*/ Some((Instruction::BRK, AddressingMode::Implied)),
|
||||||
/*0x01*/ Some((Instruction::ORA, AddressingMode::IndexedIndirectX)),
|
/*0x01*/ Some((Instruction::ORA, AddressingMode::IndexedIndirectX)),
|
||||||
/*0x02*/ None,
|
/*0x02*/ None,
|
||||||
|
@ -26,9 +26,7 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// Needed for debug! / log! macros
|
// Needed for debug! / log! macros
|
||||||
#![feature(phase)]
|
#[macro_use]
|
||||||
|
|
||||||
#[phase(plugin, link)]
|
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
pub mod address;
|
pub mod address;
|
||||||
@ -36,4 +34,3 @@ pub mod instruction;
|
|||||||
pub mod machine;
|
pub mod machine;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod registers;
|
pub mod registers;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ use registers::{ Registers, StackPointer, Status, StatusArgs };
|
|||||||
use registers::{ PS_NEGATIVE, PS_DECIMAL_MODE, PS_OVERFLOW, PS_ZERO, PS_CARRY,
|
use registers::{ PS_NEGATIVE, PS_DECIMAL_MODE, PS_OVERFLOW, PS_ZERO, PS_CARRY,
|
||||||
PS_DISABLE_INTERRUPTS };
|
PS_DISABLE_INTERRUPTS };
|
||||||
|
|
||||||
#[deriving(Copy)]
|
#[derive(Copy)]
|
||||||
pub struct Machine {
|
pub struct Machine {
|
||||||
pub registers: Registers,
|
pub registers: Registers,
|
||||||
pub memory: Memory
|
pub memory: Memory
|
||||||
@ -56,7 +56,7 @@ impl Machine {
|
|||||||
pub fn fetch_next_and_decode(&mut self) -> Option<DecodedInstr> {
|
pub fn fetch_next_and_decode(&mut self) -> Option<DecodedInstr> {
|
||||||
let x: u8 = self.memory.get_byte(self.registers.program_counter);
|
let x: u8 = self.memory.get_byte(self.registers.program_counter);
|
||||||
|
|
||||||
match instruction::OPCODES[x as uint] {
|
match instruction::OPCODES[x as usize] {
|
||||||
Some((instr, am)) => {
|
Some((instr, am)) => {
|
||||||
let extra_bytes = am.extra_bytes();
|
let extra_bytes = am.extra_bytes();
|
||||||
let num_bytes = AddressDiff(1) + extra_bytes;
|
let num_bytes = AddressDiff(1) + extra_bytes;
|
||||||
@ -85,7 +85,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
(Instruction::ADC, OpInput::UseAddress(addr)) => {
|
(Instruction::ADC, OpInput::UseAddress(addr)) => {
|
||||||
let val = self.memory.get_byte(addr) as i8;
|
let val = self.memory.get_byte(addr) as i8;
|
||||||
debug!("add with carry. address: {}. value: {}", addr, val);
|
debug!("add with carry. address: {:?}. value: {}", addr, val);
|
||||||
self.add_with_carry(val);
|
self.add_with_carry(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ impl Machine {
|
|||||||
(Instruction::BMI, OpInput::UseRelative(rel)) => {
|
(Instruction::BMI, OpInput::UseRelative(rel)) => {
|
||||||
let addr = self.registers.program_counter
|
let addr = self.registers.program_counter
|
||||||
+ AddressDiff(rel as i32);
|
+ AddressDiff(rel as i32);
|
||||||
debug!("branch if minus relative. address: {}", addr);
|
debug!("branch if minus relative. address: {:?}", addr);
|
||||||
self.branch_if_minus(addr);
|
self.branch_if_minus(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
(Instruction::LDA, OpInput::UseAddress(addr)) => {
|
(Instruction::LDA, OpInput::UseAddress(addr)) => {
|
||||||
let val = self.memory.get_byte(addr);
|
let val = self.memory.get_byte(addr);
|
||||||
debug!("load A. address: {}. value: {}", addr, val);
|
debug!("load A. address: {:?}. value: {}", addr, val);
|
||||||
self.load_accumulator(val as i8);
|
self.load_accumulator(val as i8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
(Instruction::LDX, OpInput::UseAddress(addr)) => {
|
(Instruction::LDX, OpInput::UseAddress(addr)) => {
|
||||||
let val = self.memory.get_byte(addr);
|
let val = self.memory.get_byte(addr);
|
||||||
debug!("load X. address: {}. value: {}", addr, val);
|
debug!("load X. address: {:?}. value: {}", addr, val);
|
||||||
self.load_x_register(val as i8);
|
self.load_x_register(val as i8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
(Instruction::LDY, OpInput::UseAddress(addr)) => {
|
(Instruction::LDY, OpInput::UseAddress(addr)) => {
|
||||||
let val = self.memory.get_byte(addr);
|
let val = self.memory.get_byte(addr);
|
||||||
debug!("load Y. address: {}. value: {}", addr, val);
|
debug!("load Y. address: {:?}. value: {}", addr, val);
|
||||||
self.load_y_register(val as i8);
|
self.load_y_register(val as i8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +355,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
(Instruction::SBC, OpInput::UseAddress(addr)) => {
|
(Instruction::SBC, OpInput::UseAddress(addr)) => {
|
||||||
let val = self.memory.get_byte(addr) as i8;
|
let val = self.memory.get_byte(addr) as i8;
|
||||||
debug!("subtract with carry. address: {}. value: {}",
|
debug!("subtract with carry. address: {:?}. value: {}",
|
||||||
addr, val);
|
addr, val);
|
||||||
self.subtract_with_carry(val);
|
self.subtract_with_carry(val);
|
||||||
}
|
}
|
||||||
@ -729,6 +729,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unstable)]
|
||||||
impl std::fmt::Show for Machine {
|
impl std::fmt::Show for Machine {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
write!(f, "Machine Dump:\n\nAccumulator: {}",
|
write!(f, "Machine Dump:\n\nAccumulator: {}",
|
||||||
@ -1128,8 +1129,8 @@ fn branch_if_overflow_set_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn compare_test_helper(
|
fn compare_test_helper<F: FnMut(&mut Machine, u8)> (
|
||||||
compare: |&mut Machine, u8|,
|
compare: F,
|
||||||
load_instruction: Instruction
|
load_instruction: Instruction
|
||||||
) {
|
) {
|
||||||
let mut machine = Machine::new();
|
let mut machine = Machine::new();
|
||||||
|
@ -46,48 +46,49 @@ pub const STACK_ADDRESS_HI: Address = Address(0x01FF);
|
|||||||
pub const IRQ_INTERRUPT_VECTOR_LO: Address = Address(0xFFFE);
|
pub const IRQ_INTERRUPT_VECTOR_LO: Address = Address(0xFFFE);
|
||||||
pub const IRQ_INTERRUPT_VECTOR_HI: Address = Address(0xFFFF);
|
pub const IRQ_INTERRUPT_VECTOR_HI: Address = Address(0xFFFF);
|
||||||
|
|
||||||
const MEMORY_SIZE: uint = (ADDR_HI_BARE - ADDR_LO_BARE) as uint + 1u;
|
const MEMORY_SIZE: usize = (ADDR_HI_BARE - ADDR_LO_BARE) as usize + 1us;
|
||||||
|
|
||||||
// FIXME: Should this use indirection for `bytes`?
|
// FIXME: Should this use indirection for `bytes`?
|
||||||
#[deriving(Copy)]
|
#[derive(Copy)]
|
||||||
pub struct Memory {
|
pub struct Memory {
|
||||||
bytes: [u8, ..MEMORY_SIZE]
|
bytes: [u8; MEMORY_SIZE]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
pub fn new() -> Memory {
|
pub fn new() -> Memory {
|
||||||
Memory { bytes: [0, ..MEMORY_SIZE] }
|
Memory { bytes: [0; MEMORY_SIZE] }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_byte(&self, address: Address) -> u8 {
|
pub fn get_byte(&self, address: Address) -> u8 {
|
||||||
self.bytes[address.to_uint()]
|
self.bytes[address.to_usize()]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_byte_mut_ref(&mut self, address: Address) -> &mut u8 {
|
pub fn get_byte_mut_ref(&mut self, address: Address) -> &mut u8 {
|
||||||
&mut self.bytes[address.to_uint()]
|
&mut self.bytes[address.to_usize()]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_slice(&self, Address(start): Address,
|
pub fn get_slice(&self, Address(start): Address,
|
||||||
AddressDiff(diff): AddressDiff) -> &[u8] {
|
AddressDiff(diff): AddressDiff) -> &[u8] {
|
||||||
let start = start as uint;
|
let start = start as usize;
|
||||||
let diff = diff as uint;
|
let diff = diff as usize;
|
||||||
let end = start + diff;
|
let end = start + diff;
|
||||||
self.bytes.slice(start, end)
|
&self.bytes[start..end]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the byte at the given address to the given value and returns the
|
// Sets the byte at the given address to the given value and returns the
|
||||||
// previous value at the address.
|
// previous value at the address.
|
||||||
pub fn set_byte(&mut self, address: Address, value: u8) -> u8 {
|
pub fn set_byte(&mut self, address: Address, value: u8) -> u8 {
|
||||||
let old_value = self.get_byte(address);
|
let old_value = self.get_byte(address);
|
||||||
self.bytes[address.to_uint()] = value;
|
self.bytes[address.to_usize()] = value;
|
||||||
old_value
|
old_value
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_bytes(&mut self, Address(start): Address, values: &[u8]) {
|
pub fn set_bytes(&mut self, Address(start): Address, values: &[u8]) {
|
||||||
let start = start as uint;
|
let start = start as usize;
|
||||||
|
|
||||||
// This panics if the range is invalid
|
// This panics if the range is invalid
|
||||||
let slice = self.bytes.slice_mut(start, start + values.len());
|
let end = start + values.len();
|
||||||
|
let slice = &mut self.bytes[start..end];
|
||||||
|
|
||||||
// JAM: Is this the best way to do this copy?
|
// JAM: Is this the best way to do this copy?
|
||||||
for (dest, src) in slice.iter_mut().zip(values.iter()) {
|
for (dest, src) in slice.iter_mut().zip(values.iter()) {
|
||||||
|
@ -29,7 +29,7 @@ use address::{Address, AddressDiff};
|
|||||||
use memory::{STACK_ADDRESS_LO, STACK_ADDRESS_HI};
|
use memory::{STACK_ADDRESS_LO, STACK_ADDRESS_HI};
|
||||||
|
|
||||||
// Useful for constructing Status instances
|
// Useful for constructing Status instances
|
||||||
#[deriving(Copy)]
|
#[derive(Copy)]
|
||||||
pub struct StatusArgs {
|
pub struct StatusArgs {
|
||||||
pub negative: bool,
|
pub negative: bool,
|
||||||
pub overflow: bool,
|
pub overflow: bool,
|
||||||
@ -55,7 +55,8 @@ impl StatusArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub bitflags! {
|
pub bitflags! {
|
||||||
#[deriving(Show)]
|
#[allow(unstable)]
|
||||||
|
#[derive(Show)]
|
||||||
flags Status: u8 {
|
flags Status: u8 {
|
||||||
const PS_NEGATIVE = 0b10000000,
|
const PS_NEGATIVE = 0b10000000,
|
||||||
const PS_OVERFLOW = 0b01000000,
|
const PS_OVERFLOW = 0b01000000,
|
||||||
@ -121,7 +122,7 @@ impl Status {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Copy, PartialEq, Eq, PartialOrd, Ord, Show)]
|
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Show)]
|
||||||
pub struct StackPointer(pub u8);
|
pub struct StackPointer(pub u8);
|
||||||
|
|
||||||
impl StackPointer {
|
impl StackPointer {
|
||||||
@ -144,7 +145,7 @@ impl StackPointer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Copy, PartialEq, Eq, Show)]
|
#[derive(Copy, PartialEq, Eq, Show)]
|
||||||
pub struct Registers {
|
pub struct Registers {
|
||||||
pub accumulator: i8,
|
pub accumulator: i8,
|
||||||
pub index_x: i8,
|
pub index_x: i8,
|
||||||
|
Loading…
Reference in New Issue
Block a user