{"id":30556082,"url":"https://github.com/davetcode/gameboy-emulator-dotnet","last_synced_at":"2025-10-30T01:39:17.341Z","repository":{"id":39742708,"uuid":"231447147","full_name":"DaveTCode/gameboy-emulator-dotnet","owner":"DaveTCode","description":"A gameboy (CGB \u0026 DMG) emulator written in dotnet core 3.1 C#8 with SDL/NAudio","archived":false,"fork":false,"pushed_at":"2023-03-09T17:10:58.000Z","size":17555,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-03-22T14:02:30.772Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"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/DaveTCode.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}},"created_at":"2020-01-02T19:35:19.000Z","updated_at":"2023-03-22T14:02:30.772Z","dependencies_parsed_at":"2023-02-12T03:46:48.148Z","dependency_job_id":null,"html_url":"https://github.com/DaveTCode/gameboy-emulator-dotnet","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/DaveTCode/gameboy-emulator-dotnet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveTCode%2Fgameboy-emulator-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveTCode%2Fgameboy-emulator-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveTCode%2Fgameboy-emulator-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveTCode%2Fgameboy-emulator-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DaveTCode","download_url":"https://codeload.github.com/DaveTCode/gameboy-emulator-dotnet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveTCode%2Fgameboy-emulator-dotnet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272453501,"owners_count":24937467,"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","status":"online","status_checked_at":"2025-08-28T02:00:10.768Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-08-28T06:26:42.839Z","updated_at":"2025-10-30T01:39:12.285Z","avatar_url":"https://github.com/DaveTCode.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://dev.azure.com/DavidATyler/Gameboy%20Emulator/_apis/build/status/DaveTCode.gameboy-emulator-dotnet?branchName=master)](https://dev.azure.com/DavidATyler/Gameboy%20Emulator/_build/latest?definitionId=2\u0026branchName=master)\n[![Code Coverage](https://img.shields.io/azure-devops/coverage/DavidATyler/Gameboy%20Emulator/2)](https://img.shields.io/azure-devops/coverage/DavidATyler/Gameboy%20Emulator/2)\n\n# Gameboy Emulator in C# 8\n\nGameboy (DMG \u0026 CGB) emulator written in C#8 (dotnet core 3.1) as an educational exercise (not as a production emulator). Uses SDL2 for windowing \u0026 graphics and \nNAudio for playing raw audio samples.\n\n## State\n\n- Passing test roms section at bottom of readme\n- Most DMG games are playable, most CGB games have graphical glitches although DX style games are typically ok\n- MBC1,2,3,5 all implemented and tested\n\n## TODO\n\n### Fixes\n\n- Lots of test failures specified in the table below\n- Aladdin screwed up video after boot\n- Sound channel 4 is screwed up (1 \u0026 2 seem ok if badly aliased)\n- Sounds start during copyright screen of tetris, so I've misunderstood something regarding how sounds are turned on/off. \nThink I need to rewrite the sound channels to call out the DAC as a separate unit\n\n### Specific\n\n- Complete adding integration tests for all known test roms\n- Add HDMA transfer tests\n- Test timer subsystem\n- Prevent pressing multiple buttons (just direction keys?) at a time\n- RTC for MBC3 pretends to exist but doesn't really\n- Fully update debugging spreadsheets for CGB and Audio\n\n### Ideas/Future\n\n- Display FPS using SDL text rendering?\n- Native debugger with winforms/wpf?\n- SGB support\n- Dot renderer rather than full line renderer\n- Proper configurable serial port support\n- IR port configuration\n\n### Known Tests\n\n| Test                                        | Pass                  | Notes |\n| ------------------------------------------- |:---------------------:| -----:|\n| Blargg - cpu_instrs                         | :white_check_mark:    |       |\n| Blargg - instr_timing                       | :white_check_mark:    |       |\n| Blargg - interrupt_time                     | :white_check_mark:    |       |\n| Blargg - mem_timing                         | :white_check_mark:    |       |\n| Blargg - mem_timing2                        | :white_check_mark:    |       |\n| Blargg - cgb_sound                          | :x:                   | All bar one fail, but this would fail on a DMG so doesn't matter overly |\n| Blargg - dmg_sound                          | :x:                   | All 12 fail, but this also fails on a CGB console so doesn't matter too much |\n| Blargg - halt_bug                           | :x:                   | Fails but no attempt to implement this bug |\n| Blargg - oam_bug                            | :x:                   | Fails but no attempt to implement this bug |\n| Mooneye - MBC1 - bits_bank1                 | :white_check_mark:    |       |\n| Mooneye - MBC1 - bits_bank2                 | :white_check_mark:    |       |\n| Mooneye - MBC1 - bits_mode                  | :white_check_mark:    |       |\n| Mooneye - MBC1 - bits_ramg                  | :white_check_mark:    |       |\n| Mooneye - MBC1 - ram64kb                    | :white_check_mark:    |       |\n| Mooneye - MBC1 - ram256kb                   | :white_check_mark:    |       |\n| Mooneye - MBC1 - rom512kb                   | :white_check_mark:    |       |\n| Mooneye - MBC1 - rom1Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC1 - rom2Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC1 - rom4Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC1 - rom8Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC1 - rom16Mb                    | :white_check_mark:    |       |\n| Mooneye - MBC2 - bits_ramg                  | :white_check_mark:    |       |\n| Mooneye - MBC2 - bits_romb                  | :white_check_mark:    |       |\n| Mooneye - MBC2 - bits_unused                | :white_check_mark:    |       |\n| Mooneye - MBC2 - ram                        | :white_check_mark:    |       |\n| Mooneye - MBC2 - rom1Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC2 - rom2Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC2 - rom512kb                   | :white_check_mark:    |       |\n| Mooneye - MBC5 - rom512kb                   | :white_check_mark:    |       |\n| Mooneye - MBC5 - rom1Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC5 - rom2Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC5 - rom4Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC5 - rom8Mb                     | :white_check_mark:    |       |\n| Mooneye - MBC5 - rom16Mb                    | :white_check_mark:    |       |\n| Mooneye - MBC5 - rom32Mb                    | :white_check_mark:    |       |\n| Mooneye - MBC5 - rom64Mb                    | :white_check_mark:    |       |\n| Mooneye - BITS - mem_oam                    | :white_check_mark:    |       |\n| Mooneye - BITS - reg_f                      | :white_check_mark:    |       |\n| Mooneye - BITS - unused_hwio-GS             | :white_check_mark:    |       |\n| Mooneye - Instr - daa                       | :white_check_mark:    |       |\n| Mooneye - Interrupts - ie_push              | :x:                   | Subtle bug relating to interrupt causing the PC to get put into the interrupt flag, not emulated |\n| Mooneye - OAM_DMA - basic                   | :white_check_mark:    |       |\n| Mooneye - OAM_DMA - reg_read                | :white_check_mark:    |       |\n| Mooneye - OAM_DMA - sources-GS              | :x:                   | Not supposed to pass on CGB, not really clear what this actually _does_      |\n| Mooneye - PPU - hblank_ly_scx_timing-GS     | :x:                   | Just says that the test fails without details, we do take SCX into account so this is a bit surprising      |\n| Mooneye - PPU - intr_1_2_timing-GS          | :x:                   | Register values way off what they should be |\n| Mooneye - PPU - intr_2_0_timing             | :white_check_mark:    |       |\n| Mooneye - PPU - intr_2_mode0_timing         | :white_check_mark:    |       |\n| Mooneye - PPU - intr_2_mode0_timing_sprites | :x:                   | TEST #00 FAILS      |\n| Mooneye - PPU - intr_2_mode3_timing         | :white_check_mark:    |       |\n| Mooneye - PPU - intr_2_oam_ok_timing        | :white_check_mark:    |       |\n| Mooneye - PPU - lcd_on_timing               | :x:                   | LY=1 when it should be 0 - maybe a more serious bug than the timing issues we know about      |\n| Mooneye - PPU - lcdon_write_timing          | :x:                   | Loads of bad assumptions cause this failure      |\n| Mooneye - PPU - stat_irq_blocking           | :x:                   | Unknown reason      |\n| Mooneye - PPU - stat_lyc_onoff              | :x:                   | Fail r1 step 1 reason unknown      |\n| Mooneye - PPU - vblank_stat_intr-GS         | :white_check_mark:    |       |\n| Mooneye - Timer - div_write                 | :white_check_mark:    |       |\n| Mooneye - Timer - rapid_toggle              | :x:                   | \"the timer circuit design causes some unexpected timer increases\" - unsure what this means in the test source so likely the cause of failure      |\n| Mooneye - Timer - tim00                     | :white_check_mark:    |       |\n| Mooneye - Timer - tim01                     | :white_check_mark:    |       |\n| Mooneye - Timer - tim10                     | :white_check_mark:    |       |\n| Mooneye - Timer - tim11                     | :white_check_mark:    |       |\n| Mooneye - Timer - tim00_div_trigger         | :x:                   | Precise implementation of counts and interesting behavior of div register setting values in timer required to do this and following  |\n| Mooneye - Timer - tim01_div_trigger         | :x:                   |       |\n| Mooneye - Timer - tim10_div_trigger         | :x:                   |       |\n| Mooneye - Timer - tim11_div_trigger         | :x:                   |       |\n| Mooneye - Timer - tima_reload               | :white_check_mark:    |       |\n| Mooneye - Timer - tima_write_reloading      | :x:                   | Fails, requires non-atomic CPU ops      |\n| Mooneye - Timer - tma_write_reloading       | :x:                   | Fails, requires non-atomic CPU ops      |\n| Mooneye - General - add_sp_e_timing         | :white_check_mark:    |       |\n| Mooneye - General - boot_div-dmg0           | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_div-dmgABCmgb      | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_div-S              | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_div2-S             | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_hwio-dmg0          | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_hwio-dmgABCmgb     | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_hwio-S             | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_regs-dmg0          | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_regs-dmgABC        | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_regs-mgb           | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_regs-sgb           | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - boot_regs-sgb2          | :x:                   | Only passes on specific model of device      |\n| Mooneye - General - call_cc_timing          | :white_check_mark:    |       |\n| Mooneye - General - call_cc_timing2         | :white_check_mark:    |       |\n| Mooneye - General - call_timing             | :white_check_mark:    |       |\n| Mooneye - General - call_timing2            | :white_check_mark:    |       |\n| Mooneye - General - div_timing              | :white_check_mark:    |       |\n| Mooneye - General - di_timing-GS            | :white_check_mark:    | Passes in both DMG/CGB mode when it should only pass in DMG     |\n| Mooneye - General - ei_sequence             | :white_check_mark:    |       |\n| Mooneye - General - ei_timing               | :white_check_mark:    |       |\n| Mooneye - General - halt_ime0_ei            | :white_check_mark:    |       |\n| Mooneye - General - halt_ime0_nointr_timing | :white_check_mark:    |       |\n| Mooneye - General - halt_ime1_timing        | :white_check_mark:    |       |\n| Mooneye - General - halt_ime1_timing2-GS    | :x:                   | Fails on CGB device, not sure why it fails on emulator though      |\n| Mooneye - General - if_ie_registers         | :white_check_mark:    |       |\n| Mooneye - General - intr_timing             | :white_check_mark:    |       |\n| Mooneye - General - jp_cc_timing            | :white_check_mark:    |       |\n| Mooneye - General - jp_timing               | :white_check_mark:    |       |\n| Mooneye - General - ld_hl_sp_e_timing       | :white_check_mark:    |       |\n| Mooneye - General - oam_dma_restart         | :white_check_mark:    |       |\n| Mooneye - General - oam_dma_start           | :x:                   | Something isn't quite right with restarting DMA?      |\n| Mooneye - General - oam_dma_timing          | :white_check_mark:    |       |\n| Mooneye - General - pop_timing              | :white_check_mark:    |       |\n| Mooneye - General - push_timing             | :white_check_mark:    |       |\n| Mooneye - General - rapid_di_ei             | :white_check_mark:    |       |\n| Mooneye - General - reti_intr_timing        | :white_check_mark:    |       |\n| Mooneye - General - reti_timing             | :white_check_mark:    |       |\n| Mooneye - General - ret_cc_timing           | :white_check_mark:    |       |\n| Mooneye - General - ret_timing              | :white_check_mark:    |       |\n| Mooneye - General - rst_timing              | :white_check_mark:    |       |","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavetcode%2Fgameboy-emulator-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavetcode%2Fgameboy-emulator-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavetcode%2Fgameboy-emulator-dotnet/lists"}