{"id":28237263,"url":"https://github.com/garettcooper/emulator_6502","last_synced_at":"2025-06-10T15:30:28.218Z","repository":{"id":54572247,"uuid":"207919933","full_name":"GarettCooper/emulator_6502","owner":"GarettCooper","description":"Rust implementation of an MOS 6502 emulator, intended to be a talking point during the interview process for my Winter 2020 co-op placement.","archived":false,"fork":false,"pushed_at":"2023-10-24T22:54:05.000Z","size":188,"stargazers_count":24,"open_issues_count":1,"forks_count":4,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-05-19T00:17:58.503Z","etag":null,"topics":["emulator","nes","rust"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/emulator_6502","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GarettCooper.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-11T22:48:45.000Z","updated_at":"2024-11-17T22:26:13.000Z","dependencies_parsed_at":"2022-08-13T20:10:20.048Z","dependency_job_id":null,"html_url":"https://github.com/GarettCooper/emulator_6502","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GarettCooper%2Femulator_6502","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GarettCooper%2Femulator_6502/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GarettCooper%2Femulator_6502/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GarettCooper%2Femulator_6502/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GarettCooper","download_url":"https://codeload.github.com/GarettCooper/emulator_6502/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GarettCooper%2Femulator_6502/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259100986,"owners_count":22805182,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["emulator","nes","rust"],"created_at":"2025-05-19T00:17:56.159Z","updated_at":"2025-06-10T15:30:28.184Z","avatar_url":"https://github.com/GarettCooper.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/GarettCooper/emulator_6502.svg?branch=master)](https://travis-ci.org/GarettCooper/emulator_6502)\n[![Crate](https://img.shields.io/crates/v/emulator_6502.svg)](https://crates.io/crates/emulator_6502)\n[![Documentation](https://docs.rs/emulator_6502/badge.svg)](https://docs.rs/emulator_6502)\n\n# emulator_6502\n\nHello friends, prospective employers, and people who Googled \"6502 emulator rust\", you've found\na small personal project I've been working on since early September of 2019 to use as a talking\npoint during the interview process for my Winter 2020 co-op placement. The goal of the project\nis to demonstrate my ability to pick up a new programming language while developing a complex\nsystem.\n\nThis is a general purpose Rust implementation of an [MOS 6502](https://en.wikipedia.org/wiki/MOS_Technology_6502)\nemulator, capable of executing code in isolation or as part of one of the many systems the 6502\nwas used in, including the Commodore 64, Apple II, and Nintendo Entertainment System. To do so,\nthe library provides the Interface6502 trait which allows the client to implement its own\nfunctions for reading and writing to memory addresses. For a real implementation example, check\nout my [gc_nes_emulator](https://github.com/GarettCooper/gc_nes_emulator).\n\n#### Defining an interface\n\n```rust\n\nstruct BasicRam{\n    ram: Box\u003c[u8; u16::max_value() as usize + 1]\u003e //The maximum address range of the 6502\n}\n\nimpl BasicRam {\n    fn load_program(\u0026mut self, start: usize, data: \u0026mut Vec\u003cu8\u003e){\n        self.ram[start..].clone_from_slice(data);\n    }\n}\n\nimpl Interface6502 for BasicRam{\n    fn read(\u0026mut self, address: u16) -\u003e u8{\n        self.ram[address as usize]\n    }\n\n    fn write(\u0026mut self, address: u16, data: u8){\n        self.ram[address as usize] = data\n    }\n}\n\n```\n\nIn this example, the interface to be used with the emulator simply maps addresses to ram locations.\nThe client is responsible for loading the 6502 binary program it wishes to run into an appropriate\npart of the address range. A more complex interface could map specific addresses to other emulated\ndevice components.\n\nFor example, a NES implementation using this 6502 emulator would map reads and writes to addresses\n0x2000-0x2007 to communication with the NES' picture processing unit, while a Commodore 64\nimplementation would map addresses 0xd000-0xd3ff for drawing to the screen.\n\n#### Running a program\n\n```rust\n\nfn main() -\u003e Result\u003c()\u003e{\n  let mut ram = BasicRam{ ram: Box::new([0; u16::max_value() as usize + 1]) };\n\n  //Load a program into memory...\n  let mut file = File::open(\"C:/some_6502_program.bin\")?;\n  let mut buffer = Vec::new();\n  file.read_to_end(\u0026mut buffer)?;\n\n  //Copy it into the BasicRam\n  ram.load_program(0x0400, \u0026mut buffer);\n\n  let mut cpu = MOS6502::new(); //Create a new emulator instance\n  cpu.set_program_counter(0x0400); //Set the program counter to the first byte of the program in memory\n  cpu.cycle(\u0026mut ram); // The emulator can execute cycles individually, for systems that require precise timing...\n  cpu.execute_instruction(\u0026mut ram); // or instruction by instruction for a coarser approach\n\n  Ok(())\n}\n\n```\nEach cycle/instruction the processor borrows mutable ownership of the interface in order to read and write to it.\n\nNOTE: When an instruction is executed, the entire computation is carried out simultaneously before the processor simply waits for the\nremaining number of cycles, meaning that timing of reads and writes is only accurate on an instruction-by-instruction basis, not cycle-by-cycle\n\n#### Supported Features:\n* Full implementation of documented instruction set\n* Emulation of bugs that existed in the original 6502 hardware\n* Binary Coded Decimal when the \"binary_coded_decimal\" compilation feature is enabled\n* Illegal undocumented opcodes when the \"illegal_opcodes\" compilation feature is enabled\n\nIf illegal opcodes are called without the \"illegal_opcodes\" compilation feature enabled, the emulator will log a warning\nand run for the appropriate number of cycles without changing state.\n\nCurrent version: 1.1.0\n\nLicense: MIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgarettcooper%2Femulator_6502","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgarettcooper%2Femulator_6502","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgarettcooper%2Femulator_6502/lists"}