1
0
mirror of https://github.com/mre/mos6502.git synced 2024-11-24 11:31:00 +00:00
This commit is contained in:
Matthias 2023-04-05 22:43:19 +02:00
parent 0f882e974b
commit 6a65b375c4
6 changed files with 314 additions and 46 deletions

269
Cargo.lock generated
View File

@ -2,6 +2,15 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -57,12 +66,52 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "env_logger"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
dependencies = [
"humantime",
"is-terminal",
"log",
"regex",
"termcolor",
]
[[package]]
name = "errno"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys 0.45.0",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]] [[package]]
name = "error-chain" name = "error-chain"
version = "0.12.4" version = "0.12.4"
@ -87,6 +136,18 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hermit-abi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "instant" name = "instant"
version = "0.1.12" version = "0.1.12"
@ -96,6 +157,29 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "io-lifetimes"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
dependencies = [
"hermit-abi",
"libc",
"windows-sys 0.48.0",
]
[[package]]
name = "is-terminal"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8"
dependencies = [
"hermit-abi",
"io-lifetimes",
"rustix",
"windows-sys 0.45.0",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.2" version = "1.0.2"
@ -104,9 +188,15 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.126" version = "0.2.141"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
[[package]]
name = "linux-raw-sys"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
[[package]] [[package]]
name = "log" name = "log"
@ -125,9 +215,10 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]] [[package]]
name = "mos6502" name = "mos6502"
version = "0.3.0" version = "0.4.0"
dependencies = [ dependencies = [
"bitflags 2.0.2", "bitflags 2.0.2",
"env_logger",
"log", "log",
"num", "num",
"skeptic", "skeptic",
@ -234,6 +325,23 @@ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
] ]
[[package]]
name = "regex"
version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
version = "0.5.3" version = "0.5.3"
@ -243,6 +351,20 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "rustix"
version = "0.37.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d"
dependencies = [
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys 0.45.0",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.10" version = "1.0.10"
@ -338,6 +460,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "termcolor"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "unicase" name = "unicase"
version = "2.6.0" version = "2.6.0"
@ -400,3 +531,135 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.0",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-targets"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
dependencies = [
"windows_aarch64_gnullvm 0.48.0",
"windows_aarch64_msvc 0.48.0",
"windows_i686_gnu 0.48.0",
"windows_i686_msvc 0.48.0",
"windows_x86_64_gnu 0.48.0",
"windows_x86_64_gnullvm 0.48.0",
"windows_x86_64_msvc 0.48.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"

View File

@ -53,6 +53,7 @@ default-features = false
skeptic = "0.13.7" skeptic = "0.13.7"
[dev-dependencies] [dev-dependencies]
env_logger = "0.10.0"
skeptic = "0.13.7" skeptic = "0.13.7"
[features] [features]

View File

@ -27,7 +27,6 @@
use crate::instruction::{self, AddressingMode, DecodedInstr, Instruction, OpInput}; use crate::instruction::{self, AddressingMode, DecodedInstr, Instruction, OpInput};
use crate::memory::Bus; use crate::memory::Bus;
use crate::registers::{Registers, StackPointer, Status, StatusArgs}; use crate::registers::{Registers, StackPointer, Status, StatusArgs};
fn arr_to_addr(arr: &[u8]) -> u16 { fn arr_to_addr(arr: &[u8]) -> u16 {
@ -62,6 +61,8 @@ impl<M: Bus> CPU<M> {
match instruction::OPCODES[x as usize] { match instruction::OPCODES[x as usize] {
Some((instr, am)) => { Some((instr, am)) => {
debug!("{instr:?}");
let extra_bytes = am.extra_bytes(); let extra_bytes = am.extra_bytes();
let num_bytes = extra_bytes + 1; let num_bytes = extra_bytes + 1;

View File

@ -113,7 +113,7 @@ pub enum OpInput {
UseAddress(u16), UseAddress(u16),
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone, Debug)]
pub enum AddressingMode { pub enum AddressingMode {
Accumulator, // 1 LSR A work directly on accumulator Accumulator, // 1 LSR A work directly on accumulator
Implied, // 1 BRK Implied, // 1 BRK

View File

@ -34,30 +34,37 @@
// end: Address, // end: Address,
// } // }
const ADDR_LO_BARE: u16 = 0x0000; // const ADDR_LO_BARE: u16 = 0x0000;
const ADDR_HI_BARE: u16 = 0xFFFF; // const ADDR_HI_BARE: u16 = 0xFFFF;
pub const MEMORY_ADDRESS_LO: u16 = ADDR_LO_BARE; // pub const MEMORY_ADDRESS_LO: u16 = ADDR_LO_BARE;
pub const MEMORY_ADDRESS_HI: u16 = ADDR_HI_BARE; // pub const MEMORY_ADDRESS_HI: u16 = ADDR_HI_BARE;
pub const STACK_ADDRESS_LO: u16 = 0x0100; pub const STACK_ADDRESS_LO: u16 = 0x0100;
pub const STACK_ADDRESS_HI: u16 = 0x01FF; pub const STACK_ADDRESS_HI: u16 = 0x01FF;
pub const IRQ_INTERRUPT_VECTOR_LO: u16 = 0xFFFE; pub const IRQ_INTERRUPT_VECTOR_LO: u16 = 0xFFFE;
pub const IRQ_INTERRUPT_VECTOR_HI: u16 = 0xFFFF; pub const IRQ_INTERRUPT_VECTOR_HI: u16 = 0xFFFF;
const MEMORY_SIZE: usize = (ADDR_HI_BARE - ADDR_LO_BARE) as usize + 1usize; // const MEMORY_SIZE: usize = (ADDR_HI_BARE - ADDR_LO_BARE) as usize + 1usize;
// FIXME: Should this use indirection for `bytes`?
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Memory { pub struct Memory<const MEMORY_SIZE: usize> {
bytes: [u8; MEMORY_SIZE], bytes: [u8; MEMORY_SIZE],
} }
impl Default for Memory { impl<const MEMORY_SIZE: usize> Default for Memory<MEMORY_SIZE> {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
impl<const MEMORY_SIZE: usize> Memory<MEMORY_SIZE> {
pub fn new() -> Memory<MEMORY_SIZE> {
Memory {
bytes: [0; MEMORY_SIZE],
}
}
}
pub trait Bus { pub trait Bus {
fn get_byte(&mut self, address: u16) -> u8; fn get_byte(&mut self, address: u16) -> u8;
fn set_byte(&mut self, address: u16, value: u8); fn set_byte(&mut self, address: u16, value: u8);
@ -69,15 +76,7 @@ pub trait Bus {
} }
} }
impl Memory { impl<const MEMORY_SIZE: usize> Bus for Memory<MEMORY_SIZE> {
pub fn new() -> Memory {
Memory {
bytes: [0; MEMORY_SIZE],
}
}
}
impl Bus for Memory {
fn get_byte(&mut self, address: u16) -> u8 { fn get_byte(&mut self, address: u16) -> u8 {
self.bytes[address as usize] self.bytes[address as usize]
} }

View File

@ -1,45 +1,49 @@
extern crate mos6502; extern crate mos6502;
use env_logger::Env;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use mos6502::address::Address;
use mos6502::cpu::CPU; use mos6502::cpu::CPU;
use mos6502::memory::Bus;
use mos6502::memory::Memory;
const PC_START: u16 = 0x400; const PC_START: u16 = 0x400;
// const MAX_CYCLES: usize = 100000000; // const MAX_CYCLES: usize = 100000000;
#[test] #[test]
fn functional_test() { fn functional_test() {
env_logger::init_from_env(Env::default().default_filter_or("mos6502=debug"));
let mut f = File::open("test-roms/6502_functional_test.bin").unwrap(); let mut f = File::open("test-roms/6502_functional_test.bin").unwrap();
let mut rom = Vec::<u8>::new(); let mut rom = Vec::<u8>::new();
f.read_to_end(&mut rom).unwrap(); f.read_to_end(&mut rom).unwrap();
let mut cpu = CPU::new(); let mut cpu = CPU::new(Memory::<66560>::new());
cpu.memory.set_bytes(Address(PC_START), &rom); cpu.memory.set_bytes(PC_START, &rom);
cpu.run(); // cpu.run();
/*
let mut last_pc = PC_START; let mut last_pc = PC_START;
loop { loop {
cpu.step(); cpu.single_step();
// Prevent endless loop // Prevent endless loop
if cpu.interconnect.elapsed_cycles() > MAX_CYCLES { // TODO: We could add cycle count to the CPU struct to check that
assert!(false, "Took too many cycles to complete"); // if cpu.interconnect.elapsed_cycles() > MAX_CYCLES {
} // assert!(false, "Took too many cycles to complete");
// }
if last_pc == cpu.registers.pc { if last_pc == cpu.registers.program_counter {
if cpu.registers.pc == 0x3367 { if cpu.registers.program_counter == 0x3367 {
// Success! // Success!
break; break;
} else { } else {
assert!(false, "Trap detected"); // assert!(false, "Trap detected");
} }
} }
last_pc = cpu.registers.pc; last_pc = cpu.registers.program_counter;
} }
*/
} }