{"id":21917495,"url":"https://github.com/clusterm/famicom-dumper-client","last_synced_at":"2025-03-06T16:13:19.501Z","repository":{"id":26151348,"uuid":"29596542","full_name":"ClusterM/famicom-dumper-client","owner":"ClusterM","description":"Client (PC-software) for Famicom/NES Dumper/Programmer","archived":false,"fork":false,"pushed_at":"2024-09-04T09:54:05.000Z","size":1991,"stargazers_count":67,"open_issues_count":2,"forks_count":25,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-02-27T19:15:33.665Z","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":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ClusterM.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":["ClusterM"],"custom":["https://www.buymeacoffee.com/cluster","https://boosty.to/cluster"]}},"created_at":"2015-01-21T15:38:20.000Z","updated_at":"2025-02-19T04:53:04.000Z","dependencies_parsed_at":"2024-07-16T00:28:05.891Z","dependency_job_id":"33011a5d-c75e-4509-b677-15060ceea99a","html_url":"https://github.com/ClusterM/famicom-dumper-client","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClusterM%2Ffamicom-dumper-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClusterM%2Ffamicom-dumper-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClusterM%2Ffamicom-dumper-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClusterM%2Ffamicom-dumper-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ClusterM","download_url":"https://codeload.github.com/ClusterM/famicom-dumper-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242241237,"owners_count":20095338,"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":[],"created_at":"2024-11-28T19:33:14.732Z","updated_at":"2025-03-06T16:13:19.474Z","avatar_url":"https://github.com/ClusterM.png","language":"C#","funding_links":["https://github.com/sponsors/ClusterM","https://www.buymeacoffee.com/cluster","https://boosty.to/cluster"],"categories":[],"sub_categories":[],"readme":"# Client (computer software) for Famicom/NES Dumper/Programmer\n[![Build test](https://github.com/ClusterM/famicom-dumper-client/actions/workflows/build-test.yml/badge.svg)](https://github.com/ClusterM/famicom-dumper-client/actions/workflows/build-test.yml)\n\nThis is a client for the [Famicom Dumper/Programmer](https://github.com/ClusterM/famicom-dumper-writer).\n\n[The old version](https://github.com/ClusterM/famicom-dumper) of the dumper is also partically supported.\n\nIt runs on Windows (x86, x64, arm, arm64), Linux (x64, arm, arm64) and OSX (x64, arm64)\n\n## Requirements\n.NET 6.0 is required. You need to either install the [ASP.NET Core Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) framework or to use the self-contained version.\n\n\n## Features\nIt can be used to:\n- Dump Famicom/NES cartridges using C# scripts to describe any mapper. Scripts for the most popular mappers are included.\n- Reverse engineer unknown mappers using C# scripts\n- Read/write battery-backed PRG RAM to transfer game saves\n- Read/write Famicom Disk System cards\n- (Re)write ultra-cheap COOLBOY cartridges either with soldering (old revisions) or solder-free (new) versions. It also supports both \"COOLBOY\" (with $600x registers) and \"MINDKIDS\" (with $500x registers)\n- (Re)write [COOLGIRL](https://github.com/ClusterM/coolgirl-famicom-multicard) cartridges\n- (Re)write UNROM-512 (Nesmaker) cartridges\n- Test cartridge hardware\n- Do everything described above over the network\n- Access the dumper from your C#, C++, Dart, Go, Java, Kotlin, Node, Objective-C, PHP, Python, Ruby, etc. code using gRPC\n\n\n## Usage\nIt's a command-line application.\n\nUsage: `famicom-dumper \u003ccommand\u003e [options]`\n\nAvailable commands:\n- **list-mappers** - list available mappers to dump\n- **dump** - dump cartridge\n- **server** - start gRPC server\n- **script** - execute C# script specified by --cs-file option\n- **reset** - simulate reset (M2 goes to Z-state for a second)\n- **dump-fds** - dump FDS card using RAM adapter and FDS drive\n- **write-fds** - write FDS card using RAM adapter and FDS drive\n- **read-prg-ram** - read PRG RAM (battery backed save if exists)\n- **write-prg-ram** - write PRG RAM\n- **write-coolboy** - write COOLBOY cartridge\n- **write-coolboy-gpio** - write COOLBOY cartridge using dumper's GPIO pins\n- **write-coolgirl** - write COOLGIRL cartridge\n- **write-unrom512** - write UNROM-512 cartridge\n- **info-coolboy** - show information about COOLBOY cartridge's flash memory\n- **info-coolboy-gpio** - show information about COOLBOY cartridge's flash memory using dumper's GPIO pins\n- **info-coolgirl** - show information about COOLGIRL cartridge's flash memory\n- **info-unrom512** - show information about UNROM-512 cartridge's flash memory\n\nAvailable options:\n- **--port** \u003c*com*\u003e - serial port of dumper or serial number of dumper device, default - **auto**\n- **--tcp-port** \u003c*port*\u003e - TCP port for gRPC communication, default - **26673**\n- **--host** \u003c*host*\u003e - enable gRPC client and connect to the specified host\n- **--mappers** \u003c*directory*\u003e - directory to search mapper scripts\n- **--mapper** \u003c*mapper*\u003e - number, name or path to C# script of mapper for dumping, default - **0 (NROM)**\n- **--file** \u003c*output.nes*\u003e - output/input filename (.nes, .fds, .sav, etc.)\n- **--prg-size** \u003c*size*\u003e - size of PRG memory to dump, you can use \"K\" or \"M\" suffixes\n- **--chr-size** \u003c*size*\u003e - size of CHR memory to dump, you can use \"K\" or \"M\" suffixes\n- **--prg-ram-size** - size of PRG RAM memory for NES 2.0 header, you can use \"K\" or \"M\" suffixes\n- **--chr-ram-size** - size of CHR RAM memory for NES 2.0 header, you can use \"K\" or \"M\" suffixes\n- **--prg-nvram-size** - size of PRG NVRAM memory for NES 2.0 header, you can use \"K\" or \"M\" suffixes\n- **--chr-nvram-size** - size of CHR NVRAM memory for NES 2.0 header, you can use \"K\" or \"M\" suffixes\n- **--battery** - set \"battery\" flag in ROM header after dumping\n- **--cs-file** \u003c*C#_file*\u003e - execute C# script from file\n- **--reset** - simulate reset first\n- **--unif-name** \u003c*name*\u003e - internal ROM name for UNIF dumps\n- **--unif-author** \u003c*name*\u003e - author of dump name for UNIF dumps\n- **--fds-sides** \u003c*sides*\u003e - number of FDS sides to dump (default - 1)\n- **--fds-skip-sides** \u003c*sides*\u003e - number of FDS sides to skip while writing (default - 0)\n- **--fds-no-header** - do not add header to output file during FDS dumping\n- **--fds-dump-hidden** - try to dump hidden files during FDS dumping (used for some copy-protected games)\n- **--coolboy-submapper** \u003c*submapper number*\u003e - submapper number to use while writing COOLBOY (default - **auto**, based on a ROM header)\n- **--bad-sectors** \u003c*bad_sectors*\u003e - comma separated list of bad sectors for COOLBOY/COOLGIRL writing\n- **--ignore-bad-sectors** - ignore bad sectors while writing COOLBOY/COOLGIRL\n- **--verify** - verify COOLBOY/COOLGIRL/UNROM-512/FDS after writing\n- **--lock** - write-protect COOLBOY/COOLGIRL sectors after writing\n- **--sound** - play sound when done or error occured\n\n## Notes\n**--port** option can be used to specify COM port number as \"COMx\" on Windows or as path to serial port device on Linux. Also, if you are using [old version](https://github.com/ClusterM/famicom-dumper) of the dumper, you can specify FT232 chip serial number. If this option is not not specified, port will be detected automatically based on the device name.\n\n**--mapper** option can be mapper script filename, mapper number or mapper name. If it's specified as a filename, the program will look for it in *\u003ccurrent directory\u003e/mappers* directory and */usr/share/famicom-dumper/mappers* directory (on *nix systems). **--mappers** option can be used to override directory to search. Same directories will be used to search mapper script when mapper number or mapper name is specified. Mapper number can be specified as \u003cmapper number\u003e.\u003csubmapper number\u003e in case when submapper is non-zero. Full file path also can be used.\n    \n**--file** option used in multiple cases. It's used to specify output filename when dumping cartridge. Output format will be detected based on extension: \".nes\" for iNES or NES 2.0, .unf for UNIF and \".bin\" for raw binary file. NES 2.0 container will be used in cases: when submapper is non-zero or one if the options **--prg-ram-size**, **--chr-ram-size**, **--prg-nvram-size**, **--chr-nvram-size** is set. FDS container will be used in case of dumping FDS cards. In case of cartridge/disk writing this options is used to specify input file name. File format also will be detected based on file extension.\n\n**--prg-size** and **--chr-size** options will override default cartridge memory size when dumping.\n    \n**--cs-file** is used with **script** command usually. But it's also used in case when other command is specified: script will be executed before other actions. The program will look for the script in *\u003ccurrent directory\u003e/scripts* directory and */usr/share/famicom-dumper/scripts* directory (on *nix systems). Full file path also can be used.\n    \n**--reset** options will simulate reset before command execution. **reset** command can be used to perform reset only, without any other actions.\n    \n**--lock** option used to set PPB bits of flash memory for non-empty sectors (sectors with any non-FF bytes). It's used mostly to protect cartridge from self-erase in console. This protection bits is not permanent and will be cleared before cartridre rewrite.\n    \n**--sound** option used to play built-in \"*done*\" or \"*error*\" sound on Windows. \"*bell*\" sound will be used on *nix systems in case of errors and tripple \"*bell*\" when operation is done.\n    \n## Mapper script files\nMapper scripts are written in C# language. Each script must contain class (any name allowed) that impliments [IMapper](FamicomDumper/IMapper.cs) interface.\n```C#\npublic interface IMapper\n{\n    /// \u003csummary\u003e\n    /// Name of the mapper\n    /// \u003c/summary\u003e\n    string Name { get; }\n\n    /// \u003csummary\u003e\n    /// Number of the mapper to spore in the iNES header (-1 if none)\n    /// \u003c/summary\u003e\n    int Number { get =\u003e -1; }\n\n    /// \u003csummary\u003e\n    /// Number of submapper (0 if none)\n    /// \u003c/summary\u003e\n    byte Submapper { get =\u003e 0; }\n\n    /// \u003csummary\u003e\n    /// Name of the mapper to store in UNIF container (null if none)\n    /// \u003c/summary\u003e\n    string UnifName { get =\u003e null; }\n\n    /// \u003csummary\u003e\n    /// Default PRG size to dump (in bytes)\n    /// \u003c/summary\u003e\n    int DefaultPrgSize { get; }\n\n    /// \u003csummary\u003e\n    /// Default CHR size to dump (in bytes)\n    /// \u003c/summary\u003e\n    int DefaultChrSize { get =\u003e 0; }\n\n    /// \u003csummary\u003e\n    /// This method will be called to dump PRG\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"dumper\"\u003eFamicomDumperConnection object to access cartridge\u003c/param\u003e\n    /// \u003cparam name=\"data\"\u003eThis list must be filled with dumped PRG data\u003c/param\u003e\n    /// \u003cparam name=\"size\"\u003eSize of PRG to dump requested by user (in bytes)\u003c/param\u003e\n    void DumpPrg(IFamicomDumperConnection dumper, List\u003cbyte\u003e data, int size = 0);\n\n    /// \u003csummary\u003e\n    /// This method will be called to dump CHR\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"dumper\"\u003eFamicomDumperConnection object to access cartridge\u003c/param\u003e\n    /// \u003cparam name=\"data\"\u003eThis list must be filled with dumped CHR data\u003c/param\u003e\n    /// \u003cparam name=\"size\"\u003eSize of CHR to dump requested by user (in bytes)\u003c/param\u003e\n    void DumpChr(IFamicomDumperConnection dumper, List\u003cbyte\u003e data, int size = 0)\n        =\u003e throw new NotSupportedException(\"This mapper doesn't have a CHR ROM\");\n\n    /// \u003csummary\u003e\n    /// This method will be called to enable PRG RAM\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"dumper\"\u003e\u003c/param\u003e\n    void EnablePrgRam(IFamicomDumperConnection dumper)\n        =\u003e throw new NotImplementedException(\"PRG RAM is not supported by this mapper\");\n\n    /// \u003csummary\u003e\n    /// This method must return mirroring type, it can call dumper.GetMirroring() if it's fixed\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"dumper\"\u003eFamicomDumperConnection object to access cartridge\u003c/param\u003e\n    /// \u003creturns\u003eMirroring type\u003c/returns\u003e\n    MirroringType GetMirroring(IFamicomDumperConnection dumper) =\u003e dumper.GetMirroring();\n\n    /// \u003csummary\u003e\n    /// Default PRG RAM size, can be used with NES 2.0\n    /// \u003c/summary\u003e\n    public int DefaultPrgRamSize { get =\u003e -1; }\n\n    /// \u003csummary\u003e\n    /// Default CHR RAM size, can be used with NES 2.0\n    /// \u003c/summary\u003e\n    public int DefaultChrRamSize { get =\u003e -1; }\n\n    /// \u003csummary\u003e\n    /// Default PRG NVRAM size, can be used with NES 2.0\n    /// \u003c/summary\u003e\n    public int DefaultPrgNvramSize { get =\u003e -1; }\n\n    /// \u003csummary\u003e\n    /// Default CHR NVRAM size, can be used with NES 2.0\n    /// \u003c/summary\u003e\n    public int DefaultChrNvramSize { get =\u003e -1; }\n}\n```\n\nFamicomDumperConnection implements [IFamicomDumperConnection](FamicomDumperConnection/IFamicomDumperConnection.cs) interface:\n```C#\npublic interface IFamicomDumperConnection : IDisposable\n{\n    /// \u003csummary\u003e\n    /// Simulate reset (M2 goes to Z-state for a second)\n    /// \u003c/summary\u003e\n    void Reset();\n\n    /// \u003csummary\u003e\n    /// Read single byte from CPU (PRG) bus\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"address\"\u003eAddress to read from\u003c/param\u003e\n    /// \u003creturns\u003eData from CPU (PRG) bus\u003c/returns\u003e\n    byte ReadCpu(ushort address);\n    \n    /// \u003csummary\u003e\n    /// Read data from CPU (PRG) bus\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"address\"\u003eAddress to read from\u003c/param\u003e\n    /// \u003cparam name=\"length\"\u003eNumber of bytes to read\u003c/param\u003e\n    /// \u003creturns\u003eData from CPU (PRG) bus\u003c/returns\u003e\n    byte[] ReadCpu(ushort address, int length);\n\n    /// \u003csummary\u003e\n    /// Read single byte from PPU (CHR) bus\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"address\"\u003eAddress to read from\u003c/param\u003e\n    /// \u003creturns\u003eData from PPU (CHR) bus\u003c/returns\u003e\n    byte ReadPpu(ushort address);\n\n    /// \u003csummary\u003e\n    /// Read data from PPU (CHR) bus\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"address\"\u003eAddress to read from\u003c/param\u003e\n    /// \u003cparam name=\"length\"\u003eNumber of bytes to read\u003c/param\u003e\n    /// \u003creturns\u003eData from PPU (CHR) bus\u003c/returns\u003e\n    byte[] ReadPpu(ushort address, int length);\n\n    /// \u003csummary\u003e\n    /// Write data to CPU (PRG) bus\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"address\"\u003eAddress to write to\u003c/param\u003e\n    /// \u003cparam name=\"data\"\u003eData to write, address will be incremented after each byte\u003c/param\u003e\n    void WriteCpu(ushort address, params byte[] data);\n\n    /// \u003csummary\u003e\n    /// Write data to PPU (CHR) bus\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"address\"\u003eAddress to write to\u003c/param\u003e\n    /// \u003cparam name=\"data\"\u003eData to write, address will be incremented after each byte\u003c/param\u003e\n    void WritePpu(ushort address, params byte[] data);\n\n    /// \u003csummary\u003e\n    /// Read Famicom Disk System blocks\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"startBlock\"\u003eFirst block number to read (zero-based)\u003c/param\u003e\n    /// \u003cparam name=\"maxBlockCount\"\u003eMaximum number of blocks to read\u003c/param\u003e\n    /// \u003creturns\u003eArray of Famicom Disk System blocks\u003c/returns\u003e\n    public (byte[] Data, bool CrcOk, bool EndOfHeadMeet)[] ReadFdsBlocks(byte startBlock = 0, byte maxBlockCount = byte.MaxValue);\n\n    /// \u003csummary\u003e\n    /// Write blocks to Famicom Disk System card\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"blockNumbers\"\u003eBlock numbers to write (zero-based)\u003c/param\u003e\n    /// \u003cparam name=\"blocks\"\u003eRaw blocks data\u003c/param\u003e\n    void WriteFdsBlocks(byte[] blockNumbers, byte[][] blocks);\n\n    /// \u003csummary\u003e\n    /// Write single block to Famicom Disk System card\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"blockNumbers\"\u003eBlock number to write (zero-based)\u003c/param\u003e\n    /// \u003cparam name=\"block\"\u003eRaw block data\u003c/param\u003e\n    void WriteFdsBlocks(byte blockNumber, byte[] block);\n\n    /// \u003csummary\u003e\n    /// Read raw mirroring values (CIRAM A10 pin states for different states of PPU A10 and A11)\n    /// \u003c/summary\u003e\n    /// \u003creturns\u003eValues of CIRAM A10 pin for $2000-$23FF, $2400-$27FF, $2800-$2BFF and $2C00-$2FFF\u003c/returns\u003e\n    bool[] GetMirroringRaw();\n\n    /// \u003csummary\u003e\n    /// Read decoded current mirroring mode\n    /// \u003c/summary\u003e\n    /// \u003creturns\u003eCurrent mirroring\u003c/returns\u003e\n    MirroringType GetMirroring();\n}\n```\n\nCheck \"mappers\" directory for examples.\n\n\n## Other scripts\nYou can create and run custom C# scripts to interact with dumper and cartridge. It's usefull for reverse engineering. Each script must contain class (any name allowed) that contains **Run** method. You can specify those parameters in any order:\n\n*  `IFamicomDumperConnection dumper` - dumper object used to access dumper\n*  `string filename`                 - filename specified by --file argument\n*  `IMapper mapper`                  - mapper object compiled from mapper script specified by --mapper argument\n*  `int prgSize`                     - PRG size specified by --prg-size argument (parsed)\n*  `int chrSize`                     - CHR size specified by --chr-size argument (parsed)\n*  `int prgRamSize`                  - PRG RAM size specified by --prg-ram-size argument (parsed)\n*  `int chrRamSize`                  - CHR RAM size specified by --chr-ram-size argument (parsed)\n*  `int prgNvramSize`                - PRG NVRAM size specified by --prg-nvram-size argument (parsed)\n*  `int chrNvramSize`                - CHR NVRAM size specified by --chr-nvram-size argument (parsed)\n*  `string unifName`                 - string specified by --unif-name argument\n*  `string unifAuthor`               - string specified by --unif-author argument\n*  `bool battery`                    - true if --battery argument is specified\n*  `string[] args`                   - additional command line arguments\n\nYou can specify additional arguments this way: \u003efamicom-dumper script --cs-file DemoScript.cs - argument1 argument2 argument3\n\nAlways define default value if parameter is optional. The only exception is the \"**mapper**\" parameter, the \"NROM\" mapper will be used by default. Also **args** will be a zero-length array if additional arguments are not specified.\n\nExample:\n```C#\nclass DemoScript // Class name doesn't matter\n{\n    void Run(IFamicomDumperConnection dumper, string[] args, IMapper mapper, int prgSize = 128 * 1024, int chrSize = -1)\n    {\n        if (mapper.Number \u003e= 0)\n            Console.WriteLine($\"Using mapper: #{mapper.Number} ({mapper.Name})\");\n        else\n            Console.WriteLine($\"Using mapper: {mapper.Name}\");\n\n        if (chrSize \u003c 0)\n        {\n            // Oh no, CHR size is not specified! Lets use mapper's default\n            chrSize = mapper.DefaultChrSize;\n        }\n\n        Console.WriteLine($\"PRG size: {prgSize}\");\n        Console.WriteLine($\"CHR size: {chrSize}\");\n\n        if (args.Any())\n            Console.WriteLine(\"Additional command line arguments: \" + string.Join(\", \", args));\n\n        // You can use other methods\n        Reset(dumper);\n    }\n\n    void Reset(IFamicomDumperConnection dumper)\n    {\n        Console.Write(\"Reset... \");\n        dumper.Reset();\n        Console.WriteLine(\"OK\");\n    }\n}\n```\n     \nScript will be compiled and **Run** method will be executed if **--cs-file** option is specified. Also you can use [NesFile](https://github.com/ClusterM/nes-containers/blob/master/NesFile.cs) and [UnifFile](https://github.com/ClusterM/nes-containers/blob/master/UnifFile.cs) containers.\n\nYou can run script alone like this:\n```\nfamicom-dumper script --cs-file DemoScript.cs\n```\nOr execute it before main action like this:\n```\nfamicom-dumper dump --mapper MMC3 --file game.nes --cs-file DemoScript.cs\n```\n\nSo you can write your own code to interact with dumper object and read/write data from/to cartridge. This dumper object can be even on another PC (read below)! Check \"scripts\" directory for example scripts.\n\n\n## gRPC\nYou can start this application as gRPC server on one PC:\n```\nfamicom-dumper server --port COM14\n```\n\nAnd dump cartridge over the network using another PC:\n```\nfamicom-dumper dump --mapper CNROM --file game.nes --host example.com\n```\n\nIt's useful if you want to reverse engineer cartridge of your remote friend. You can use all commands and scripts to interact with remote dumper just like it's connected locally.\n\nAlso you can use gRPC to access dumper from other applications or your own code written in C#, C++, Dart, Go, Java, Kotlin, Node, Objective-C, PHP, Python, Ruby, etc. languages. Use [Dumper.proto](https://github.com/ClusterM/famicom-dumper-client/blob/master/FamicomDumperConnection/Dumper.proto) to automatically generate client code.\n\n\n## Examples\nDump NROM-cartridge using dumper on port \"COM14\" to the file \"game.nes\". PRG and CHR sizes are default.\n~~~~\n \u003e famicom-dumper dump --port COM14 --mapper nrom --file game.nes\n Dumper initialization... OK\n Using mapper: #0 (NROM)\n Dumping...\n PRG memory size: 32K\n Dumping PRG... OK\n CHR memory size: 8K\n Dumping CHR... OK\n Mirroring: Horizontal\n Saving to game.nes... OK\n~~~~\n\nDump MMC1-cartridge (iNES mapper #1) using dumper with FTDI serial number \"A9Z1A0WD\" and save it to game.nes file. PRG size is 128 kilobytes, CHR size is 128 kilobytes too.\n~~~~\n\u003efamicom-dumper dump --port A9Z1A0WD --mapper 1 --prg-size 128K --chr-size 128K --file game.nes\nDumper initialization... OK\nUsing mapper: #1 (MMC1)\nDumping...\nPRG memory size: 128K\nReading PRG bank #0... OK\nReading PRG bank #1... OK\nReading PRG bank #2... OK\nReading PRG bank #3... OK\n...\nSaving to game.nes... OK\n~~~~\n\nDump 32K of PRG and 8K of CHR as simple NROM cartridge but execute C# script first:\n~~~~\n\u003efamicom-dumper dump --port /dev/ttyUSB0 --mapper 0 --prg-size 32K --chr-size 8K --file game.nes --cs-file init.cs\nDumper initialization... OK\nCompiling init.cs...\nRunning init.Run()...\nDumping...\nPRG memory size: 32K\nDumping PRG... OK\nCHR memory size: 8K\nDumping CHR... OK\nMirroring: Horizontal\nSaving to game.nes... OK\n~~~~\n\nDump 32MBytes of COOLBOY cartridge using C# script and save it as UNIF file with some extra info:\n~~~~\n\u003efamicom-dumper dump --port COM14 --mapper mappers\\coolboy.cs --prg-size 32M --file coolboy.unf --unifname \"COOLBOY 400-IN-1\" --unifauthor \"John Smith\"\nDumper initialization... OK\nUsing mapper: COOLBOY\nDumping...\nPRG memory size: 32768K\nReading PRG banks #0/0 and #0/1...\nReading PRG banks #0/2 and #0/3...\nReading PRG banks #0/4 and #0/5...\n...\nSaving to coolboy.unf... OK\n~~~~\n\nDump 32MBytes of COOLBOY cartridge using C# script and save it as NES 2.0 file with some extra info:\n~~~~\n\u003efamicom-dumper dump --port COM14 --mapper mappers\\coolboy.cs --prg-size 32M --file coolboy.nes --prg-nvram-size 8K --chr-ram-size 256K\nDumper initialization... OK\nUsing mapper: COOLBOY\nDumping...\nPRG memory size: 32768K\nReading PRG banks #0/0 and #0/1...\nReading PRG banks #0/2 and #0/3...\nReading PRG banks #0/4 and #0/5...\n...\nSaving to coolboy.unf... OK\n~~~~\n\nRead battery-backed save from MMC1 cartridge:\n~~~~\n\u003efamicom-dumper read-prg-ram --port COM14 --mapper mmc1 --file zelda.sav\nDumper initialization... OK\nUsing mapper: #1 (MMC1)\nReading PRG-RAM... OK\n~~~~\n\nWrite battery-backed save back to MMC1 cartridge:\n~~~~\n\u003efamicom-dumper write-prg-ram --port COM14 --mapper mmc1 --file zelda_hacked.sav\nDumper initialization... OK\nUsing mapper: #1 (MMC1)\nWriting PRG-RAM... OK\n~~~~\n\nRewrite ultracheap chinese COOLBOY cartridge and play sound when it's done:\n~~~~\n\u003efamicom-dumper write-coolboy --port COM14 --file \"CoolBoy 400-in-1 (Alt Version, 403 games)(Unl)[U][!].nes\" --sound\nDumper initialization... OK\nReset... OK\nErasing sector... OK\nWriting 1/2048 (0%, 00:00:02/00:40:53)...\n...\n~~~~\n\nAlso you can write [COOLGIRL](https://github.com/ClusterM/coolgirl-famicom-multicard) cartridges:\n~~~~\n\u003efamicom-dumper write-coolgirl --file multirom.unf --port COM14\nDumper initialization... OK\nReset... OK\nErasing sector... OK\nWriting bank #0/114 (0%, 00:00:02/00:00:02)... OK\nWriting bank #1/114 (0%, 00:00:02/00:00:02)... OK\nWriting bank #2/114 (1%, 00:00:02/00:00:02)... OK\nWriting bank #3/114 (2%, 00:00:02/00:00:02)... OK\nErasing sector... OK\nWriting bank #4/114 (3%, 00:00:03/00:00:29)... OK\n...\n~~~~\n\nDump two-sided Famicom Disk System card:\n~~~~\n\u003efamicom-dumper dump-fds --fds-sides 2 --file game.fds\nAutodetected virtual serial port: COM13\nDumper initialization... OK\nReading disk... Done\nDisk info block:\n Game name: MET\n Manufacturer code: Nintendo\n Game type: normal disk\n Game version: 2\n Disk number: 0\n Disk side: A\n Actual disk side: $FF\n Disk type: FMS\n Manufacturing date: 1986.09.09\n Country code: Japan\n Disk writer serial number: $0961\n Disk rewrite count: 0\n Price code: $FF\nNumber of non-hidden files: 15\n...\nPlease remove disk card... OK\nPlease set disk card, side #2...\n...\nSaving to game.fds... OK\n~~~~\n\nWrite Famicom Disk System card and verify written data:\n~~~\n\u003efamicom-dumper write-fds --verify --file \"Super Mario Brothers 2 (Japan).fds\"\nAutodetected virtual serial port: COM6\nDumper initialization... OK\nPlease set disk card, side #1... OK\nDisk info block:\n Game name: SMB\n Manufacturer code: Nintendo\n Game type: normal disk\n Game version: 0\n Disk number: 0\n Disk side: A\n Actual disk side: A\n Disk type: FMS\n Manufacturing date: 1986.07.23\n Country code: Japan\n Disk writer serial number: $FFFF\n Disk rewrite count: 0\n Price code: $00\nNumber of non-hidden files: 8\nNumber of hidden files: 0\nTotal blocks to write: 18\nWriting block(s): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17... OK\nStarting verification process\nReading disk... Done\nVerification successful.\n~~~\n\nStart server on TCP port 9999 and let other person to dump cartridge over network:\n~~~~\n\u003efamicom-dumper server --tcp-port 9999\nAutodetected virtual serial port: COM13\nDumper initialization... OK\nListening port 9999, press Ctrl-C to stop\n~~~~\n\nConnect to remote dumper using TCP port 9999 and execute C# script:\n~~~~\nfamicom-dumper script --cs-file DemoScript.cs --host clusterrr.com --tcp-port 9999\nDumper initialization... OK\nCompiling DemoScript.cs...\nRunning DemoScript.Run()...\n~~~~\n\n\n## Download\nYou can always download the latest version at [https://github.com/ClusterM/famicom-dumper-client/releases](https://github.com/ClusterM/famicom-dumper-client/releases).\n\nAlso, you can download automatic interim builds at [http://clusterm.github.io/famicom-dumper-client/](http://clusterm.github.io/famicom-dumper-client/).\n\n\n## Donate\n* [Buy Me A Coffee](https://www.buymeacoffee.com/cluster)\n* [Donation Alerts](https://www.donationalerts.com/r/clustermeerkat)\n* [Boosty](https://boosty.to/cluster)\n* BTC: 1MBYsGczwCypXhMBocoDQWxx7KZT2iiwzJ\n* PayPal is not available in Armenia :(\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclusterm%2Ffamicom-dumper-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclusterm%2Ffamicom-dumper-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclusterm%2Ffamicom-dumper-client/lists"}