{"id":19478564,"url":"https://github.com/justin-credible/space-invaders-emulator","last_synced_at":"2025-04-25T15:30:47.591Z","repository":{"id":66348416,"uuid":"208955435","full_name":"Justin-Credible/space-invaders-emulator","owner":"Justin-Credible","description":"👾  An emulator for the Space Invaders arcade machine (Intel 8080 CPU).","archived":false,"fork":false,"pushed_at":"2022-11-30T07:31:44.000Z","size":2982,"stargazers_count":15,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-03T23:22:53.110Z","etag":null,"topics":["disassembler","emulator","intel8080","space-invaders"],"latest_commit_sha":null,"homepage":"https://www.justin-credible.net/2020/03/31/space-invaders-emulator/","language":"C#","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Justin-Credible.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-17T03:56:38.000Z","updated_at":"2025-02-03T20:06:40.000Z","dependencies_parsed_at":"2023-07-24T14:45:10.460Z","dependency_job_id":null,"html_url":"https://github.com/Justin-Credible/space-invaders-emulator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Justin-Credible%2Fspace-invaders-emulator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Justin-Credible%2Fspace-invaders-emulator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Justin-Credible%2Fspace-invaders-emulator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Justin-Credible%2Fspace-invaders-emulator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Justin-Credible","download_url":"https://codeload.github.com/Justin-Credible/space-invaders-emulator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250844213,"owners_count":21496524,"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":["disassembler","emulator","intel8080","space-invaders"],"created_at":"2024-11-10T19:50:33.892Z","updated_at":"2025-04-25T15:30:47.575Z","avatar_url":"https://github.com/Justin-Credible.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Space Invaders Emulator\n\nThis repository contains my implementation of an emulator for the Intel 8080 CPU and the related hardware for the 1978 arcade game: *Space Invaders*.\n\nIt emulates the graphics and sound, supports save states, has an interactive debugger, has rewind functionality, and includes 600+ unit test cases.\n\n![showcase](.readme/gameplay.gif)\n\n## Implementation\n\nI wrote the emulator and disassembler in C# targeting the cross-platform [.NET Core](https://dotnet.microsoft.com/) runtime.\n\nI used [SDL2](https://www.libsdl.org/) and [SDL2_mixer](https://www.libsdl.org/projects/SDL_mixer/) for the GUI and audio via the [SDL2#](https://github.com/flibitijibibo/SDL2-CS) wrapper.\n\nThe controls are hardcoded as:\n\n* Insert Coin: `5`\n* 1 Player Start: `1`\n* 2 Player Start: `2`\n* Player 1 - Left/Right: `left arrow` / `right arrow`\n* Player 1 - Fire: `space`\n* Player 2 - Left/Right: `a` / `d`\n* Player 2 - Fire: `p`\n* Tilt: `t`\n* Break/Debug: `BREAK` / `PAUSE` / `9`\n\n## Compiling / Running\n\n1. Install [.NET Core](https://dotnet.microsoft.com/download) 3.1\n2. Install [SDL2](https://www.libsdl.org/download-2.0.php) and [SDL2_mixer](https://www.libsdl.org/projects/SDL_mixer/)\n3. Clone this repository\n4. `cd emulator`\n5. `dotnet restore`\n6. `dotnet run --` followed by the commands to pass to the CLI program\n\nCurrently there is only one command, `run`:\n\n```\n$ dotnet run -- run --help\n\nUsage: siemu run [arguments] [options]\n\nArguments:\n  [ROM path]  The path to a directory containing the Space Invaders ROM set to load.\n\nOptions:\n  -?|-h|--help          Show help information\n  -sfx|--sound-effects  The path to a directory containing the WAV sound effects to be used.\n  -ss|--starting-ships  Specify the number of ships the player starts with; 3 (default), 4, 5, or 6.\n  -es|--extra-ship      Specify the number points needed to get an extra ship; 1000 (default) or 1500.\n  -l|--load-state       Loads an emulator save state from the given path.\n  -d|--debug            Run in debug mode; enables internal statistics and logs useful when debugging.\n  -b|--break            Used with debug, will break at the given address and allow single stepping opcode execution (e.g. --break 0x0248)\n  -r|--rewind           Used with debug, allows for single stepping in reverse to rewind opcode execution.\n  -a|--annotations      Used with debug, a path to a text file containing memory address annotations for interactive debugging (line format: 0x1234 .... ; Annotation)\n```\n\nFor example: `dotnet run -- run ../roms --sfx ../roms --starting-ships 6`\n\n## Interactive Debugger\n\nIf the emulator is launched with the `--debug` option, the debugger will be enabled. You can press the `pause`/`break` or `9` key which will stop execution and print the interactive debugger in the console.\n\n![showcase](.readme/debugger.png)\n\nFrom there you can use `F1` and `F2` to **save** and **load** the emulator **state**.\n\nTo **single step** over an opcode use `F10`, or `F5` to **continue** until the next breakpoint.\n\n**Breakpoints** can be set via the `--break` option at startup, or in the debugger by pressing `F4`.\n\nIf the emulator was started with the `--annotations` option, `F11` can be used to toggle between the disassembler's generated psuedocode or the provided annotation file. This is used to **show comments for each disassembled opcode** inline in the debugger, which makes tracking down issues and/or understanding the game code easier. I collected annotations from the amazing [Computer Archeology](http://computerarcheology.com/) page on [Space Invaders Code](http://computerarcheology.com/Arcade/SpaceInvaders/Code.html), and placed them at [`roms/annotations.txt`](roms/annotations.txt).\n\n`F12` is used to print the last 30 opcodes, so you can see **execution history**.\n\nFinally, if `--rewind` was specified at startup, `F9` can be used to single step _backwards_ over opcodes, effectively allowing you to **rewind CPU state one instruction at a time**. I found this to be very helpful when tracking down bugs in the CPU core.\n\n## Unit Tests\n\nWhile building the emulator I found it essential to write unit tests for each opcode and along the way. This made it much easier to track down bugs late in development.\n\nEach opcode test contains Intel 8080 assembly code which is assembled using [zasm](https://k1.spdns.de/Develop/Projects/zasm/Distributions/). This assembled binary is then executed on the emulated CPU and then has assertions ran against the CPU state to verify opcode behavior.\n\nAdditionally, there is an [integration test](intel8080.tests/Tests/CPUIntegrationTest.cs) which uses a CPU test program written for the Intel 8080 CPU _originally from 1980_! The assembled program along with its disassembly can can be found in the [`intel8080.tests/CPUDiag`](intel8080.tests/CPUDiag) directory.\n\nEmulator tests (9 test cases):\n1. `cd emulator.tests`\n2. `dotnet restore`\n3. `dotnet test`\n\nIntel 8080 CPU tests (605 test cases):\n1. `cd intel8080.tests`\n2. `dotnet restore`\n3. `dotnet test`\n\n## Disassembler\n\nWhile the disassembler is mainly used by the interactive debugger, it can be run from the command line as well:\n\n1. `cd disassembler`\n2. `dotnet restore`\n3. `dotnet run --` followed by the commands to pass to the CLI program\n\nCurrently there is only one command, `disassemble`:\n\n```\n$ dotnet run -- disassemble --help\n\nUsage: i8080disasm disassemble [arguments] [options]\n\nArguments:\n  [ROM path]  The path to the ROM file to disassemble (or directory containing invaders.e through .h).\n\nOptions:\n  -?|-h|--help     Show help information\n  -o|--output      The path to the to output file.\n  -a|--address     Include addresses in the disassembly.\n  -p|--pseudocode  Include pseudocode in the disassembly (a comment on each line).\n```\n\nFor exmaple: `dotnet run -- disassemble ../roms -a -p -o ../roms/output.asm`\n\n## Resources\n\nI found the following resources useful in building this emulator:\n\n* [Intel 8080 Assembly Programming Manual](https://www.google.com/search?q=intel+8080+assembly+language+programming+manual)\n  * [Mirror 1](https://altairclone.com/downloads/manuals/8080%20Programmers%20Manual.pdf)\n  * [Mirror 2](http://www.classiccmp.org/dunfield/r/8080asm.pdf)\n  * [Mirror 3](http://www.nj7p.org/Manuals/PDFs/Intel/9800004C.pdf)\n* [Intel 8080 Instruction Set](https://www.pastraiser.com/cpu/i8080/i8080_opcodes.html)\n* [Emulator 101](http://www.emulator101.com/welcome.html)\n  * [8080 Opcodes](http://www.emulator101.com/8080-by-opcode.html)\n* [Computer Archeology - Space Invaders](http://computerarcheology.com/Arcade/SpaceInvaders/)\n  * [Hardware](http://computerarcheology.com/Arcade/SpaceInvaders/Hardware.html)\n  * [Code](http://computerarcheology.com/Arcade/SpaceInvaders/Code.html)\n* 8080/8080 CPU Diagnostics Program\n  * [Source](https://github.com/begoon/i8080-core/blob/master/TEST.ASM)\n  * [Assembled Version](http://www.emulator101.com/files/cpudiag.bin)\n* [Intel 8080 CPU Emulator](https://www.tramm.li/i8080/index.html)\n* [zasm Disassembler](https://k1.spdns.de/Develop/Projects/zasm/Distributions/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustin-credible%2Fspace-invaders-emulator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjustin-credible%2Fspace-invaders-emulator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustin-credible%2Fspace-invaders-emulator/lists"}