From 6a65b375c464ecebe9e52fdfb22e27bfc6be6d49 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 5 Apr 2023 22:43:19 +0200 Subject: [PATCH] wip --- Cargo.lock | 269 ++++++++++++++++++++++++++++++++++++++- Cargo.toml | 1 + src/cpu.rs | 3 +- src/instruction.rs | 2 +- src/memory.rs | 33 +++-- tests/functional-test.rs | 52 ++++---- 6 files changed, 314 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01b7939..2a69295 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. 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]] name = "autocfg" version = "1.1.0" @@ -57,12 +66,52 @@ dependencies = [ "serde_json", ] +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "error-chain" version = "0.12.4" @@ -87,6 +136,18 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "instant" version = "0.1.12" @@ -96,6 +157,29 @@ dependencies = [ "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]] name = "itoa" version = "1.0.2" @@ -104,9 +188,15 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.141" 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]] name = "log" @@ -125,9 +215,10 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mos6502" -version = "0.3.0" +version = "0.4.0" dependencies = [ "bitflags 2.0.2", + "env_logger", "log", "num", "skeptic", @@ -234,6 +325,23 @@ dependencies = [ "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]] name = "remove_dir_all" version = "0.5.3" @@ -243,6 +351,20 @@ dependencies = [ "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]] name = "ryu" version = "1.0.10" @@ -338,6 +460,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + [[package]] name = "unicase" version = "2.6.0" @@ -400,3 +531,135 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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" diff --git a/Cargo.toml b/Cargo.toml index 575d9be..36c61eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ default-features = false skeptic = "0.13.7" [dev-dependencies] +env_logger = "0.10.0" skeptic = "0.13.7" [features] diff --git a/src/cpu.rs b/src/cpu.rs index a2a0d0c..1afd71c 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -27,7 +27,6 @@ use crate::instruction::{self, AddressingMode, DecodedInstr, Instruction, OpInput}; use crate::memory::Bus; - use crate::registers::{Registers, StackPointer, Status, StatusArgs}; fn arr_to_addr(arr: &[u8]) -> u16 { @@ -62,6 +61,8 @@ impl CPU { match instruction::OPCODES[x as usize] { Some((instr, am)) => { + debug!("{instr:?}"); + let extra_bytes = am.extra_bytes(); let num_bytes = extra_bytes + 1; diff --git a/src/instruction.rs b/src/instruction.rs index 885452e..996eddc 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -113,7 +113,7 @@ pub enum OpInput { UseAddress(u16), } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum AddressingMode { Accumulator, // 1 LSR A work directly on accumulator Implied, // 1 BRK diff --git a/src/memory.rs b/src/memory.rs index dbe46b5..df2c3c8 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -34,30 +34,37 @@ // end: Address, // } -const ADDR_LO_BARE: u16 = 0x0000; -const ADDR_HI_BARE: u16 = 0xFFFF; +// const ADDR_LO_BARE: u16 = 0x0000; +// const ADDR_HI_BARE: u16 = 0xFFFF; -pub const MEMORY_ADDRESS_LO: u16 = ADDR_LO_BARE; -pub const MEMORY_ADDRESS_HI: u16 = ADDR_HI_BARE; +// pub const MEMORY_ADDRESS_LO: u16 = ADDR_LO_BARE; +// pub const MEMORY_ADDRESS_HI: u16 = ADDR_HI_BARE; pub const STACK_ADDRESS_LO: u16 = 0x0100; pub const STACK_ADDRESS_HI: u16 = 0x01FF; pub const IRQ_INTERRUPT_VECTOR_LO: u16 = 0xFFFE; 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)] -pub struct Memory { +pub struct Memory { bytes: [u8; MEMORY_SIZE], } -impl Default for Memory { +impl Default for Memory { fn default() -> Self { Self::new() } } +impl Memory { + pub fn new() -> Memory { + Memory { + bytes: [0; MEMORY_SIZE], + } + } +} + pub trait Bus { fn get_byte(&mut self, address: u16) -> u8; fn set_byte(&mut self, address: u16, value: u8); @@ -69,15 +76,7 @@ pub trait Bus { } } -impl Memory { - pub fn new() -> Memory { - Memory { - bytes: [0; MEMORY_SIZE], - } - } -} - -impl Bus for Memory { +impl Bus for Memory { fn get_byte(&mut self, address: u16) -> u8 { self.bytes[address as usize] } diff --git a/tests/functional-test.rs b/tests/functional-test.rs index 2fdc85e..7edc53a 100644 --- a/tests/functional-test.rs +++ b/tests/functional-test.rs @@ -1,45 +1,49 @@ extern crate mos6502; +use env_logger::Env; + use std::fs::File; use std::io::Read; -use mos6502::address::Address; use mos6502::cpu::CPU; +use mos6502::memory::Bus; +use mos6502::memory::Memory; const PC_START: u16 = 0x400; // const MAX_CYCLES: usize = 100000000; #[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 rom = Vec::::new(); 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; - - loop { - cpu.step(); - // Prevent endless loop - if cpu.interconnect.elapsed_cycles() > MAX_CYCLES { - assert!(false, "Took too many cycles to complete"); + let mut last_pc = PC_START; + + loop { + cpu.single_step(); + // Prevent endless loop + // TODO: We could add cycle count to the CPU struct to check that + // if cpu.interconnect.elapsed_cycles() > MAX_CYCLES { + // assert!(false, "Took too many cycles to complete"); + // } + + if last_pc == cpu.registers.program_counter { + if cpu.registers.program_counter == 0x3367 { + // Success! + break; + } else { + // assert!(false, "Trap detected"); } - - if last_pc == cpu.registers.pc { - if cpu.registers.pc == 0x3367 { - // Success! - break; - } else { - assert!(false, "Trap detected"); - } - } - - last_pc = cpu.registers.pc; } - */ + + last_pc = cpu.registers.program_counter; + } }