{"id":16438751,"url":"https://github.com/beevik/go6502","last_synced_at":"2025-04-09T22:18:01.900Z","repository":{"id":22103046,"uuid":"25433327","full_name":"beevik/go6502","owner":"beevik","description":"6502 CPU emulator, assembler, disassembler, debugger and host written in go","archived":false,"fork":false,"pushed_at":"2025-01-30T05:08:11.000Z","size":1471,"stargazers_count":64,"open_issues_count":0,"forks_count":11,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-09T22:17:58.166Z","etag":null,"topics":["6502","assembler","debugger","disassembler","emulator","go"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/beevik.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-10-19T16:52:49.000Z","updated_at":"2025-03-05T19:35:27.000Z","dependencies_parsed_at":"2024-05-19T22:33:18.278Z","dependency_job_id":"675cb799-87f1-4ce4-9f64-4e01ea386f41","html_url":"https://github.com/beevik/go6502","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/beevik%2Fgo6502","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beevik%2Fgo6502/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beevik%2Fgo6502/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beevik%2Fgo6502/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beevik","download_url":"https://codeload.github.com/beevik/go6502/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248119286,"owners_count":21050755,"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":["6502","assembler","debugger","disassembler","emulator","go"],"created_at":"2024-10-11T09:06:04.428Z","updated_at":"2025-04-09T22:18:01.867Z","avatar_url":"https://github.com/beevik.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GoDoc](https://godoc.org/github.com/beevik/go6502?status.svg)](https://godoc.org/github.com/beevik/go6502)\n\ngo6502\n======\n\ngo6502 is a collection of go packages that emulate a 6502 or 65C02 CPU. It\nincludes a CPU emulator, a cross-assembler, a disassembler, a debugger, and a\nhost that wraps them all together.\n\nThe interactive go6502 console application in the root directory provides\naccess to all of these features.\n\n\n# Building the application\n\nInstall go 1.21 or later, and then run `go build` to build the application.\n\n\n# Tutorial\n\nStart by considering the go6502 `sample.cmd` script:\n\n```\nload monitor.bin $F800\nassemble file sample.asm\nload sample.bin\nreg PC START\nd .\n```\n\nWe'll describe what each of these commands does in greater detail later, but\nfor now know that they do the following things:\n1. Load the `monitor.bin` binary file at memory address `F800`.\n2. Assemble the `sample.asm` file using the go6502 cross-assembler, generating\n   a `sample.bin` binary file and a `sample.map` source map file.\n3. Load the `sample.bin` binary file and its corresponding `sample.map` source\n   map file. The binary data is loaded into memory at the origin address\n   exported during assembly into the `sample.map` file.\n4. Set the program counter register to value of the `START` address, which\n   was exported during assembly into the `sample.map` file.\n5. Disassemble the first few lines of machine code starting from the program\n   counter address.\n\nTo run this script, type the following on the command line:\n\n```\ngo6502 sample.cmd\n```\n\nYou should then see:\n\n```\nLoaded 'monitor.bin' to $F800..$FFFF.\nAssembled 'sample.asm' to 'sample.bin'.\nLoaded source map from 'sample.bin'.\nLoaded 'sample.bin' to $1000..$10FF.\nRegister PC set to $1000.\nBreakpoint added at $1020.\n1000-   A2 EE       LDX   #$EE\n1002-   A9 05       LDA   #$05\n1004-   20 19 10    JSR   $1019\n1007-   20 1C 10    JSR   $101C\n100A-   20 36 10    JSR   $1036\n100D-   20 46 10    JSR   $1046\n1010-   F0 06       BEQ   $1018\n1012-   A0 3B       LDY   #$3B\n1014-   A9 10       LDA   #$10\n1016-   A2 56       LDX   #$56\n\n1000-   A2 EE       LDX   #$EE      A=00 X=00 Y=00 PS=[------] SP=FF PC=1000 C=0\n*\n```\n\nThe output shows the result of running each sample script command. Once the\nscript has finished running, go6502 enters interactive mode and displays a `*`\nprompt for further input.\n\nJust before the prompt is a line starting with `1000-`. This line displays the\ndisassembly of the instruction at the current program counter address and the\nstate of the CPU registers. The `C` value indicates the number of CPU cycles\nthat have elapsed since the application started.\n\n## Getting help\n\nLet's enter our first interactive command. Type `help` to see a list of all\ncommands.\n\n```\ngo6502 commands:\n    annotate         Annotate an address\n    assemble         Assemble commands\n    breakpoint       Breakpoint commands\n    databreakpoint   Data breakpoint commands\n    disassemble      Disassemble code\n    evaluate         Evaluate an expression\n    execute          Execute a go6502 script file\n    exports          List exported addresses\n    load             Load a binary file\n    memory           Memory commands\n    quit             Quit the program\n    register         View or change register values\n    run              Run the CPU\n    set              Set a configuration variable\n    step             Step the debugger\n\n*\n```\n\nTo get more information about a command, type `help` followed by the command\nname. In some cases, you will be shown a list of subcommands that must be used\nwith the command. Let's try `help step`.\n\n```\n* help step\nStep commands:\n    in               Step into next instruction\n    over             Step over next instruction\n\n*\n```\n\nThis response indicates that the `step` command has two possible subcommands.\nFor example, if you wanted to step the CPU into the next instruction, you\nwould type `step in`.\n\nNow let's get help on the `step in` command.\n\n```\n* help step in\nUsage: step in [\u003ccount\u003e]\n\nDescription:\n   Step the CPU by a single instruction. If the instruction is a subroutine\n   call, step into the subroutine. The number of steps may be specified as an\n   option.\n\nShortcut: si\n\n*\n```\n\nEvery command has help text like this. Included in the help text is a\ndescription of the command, a list of shortcuts that can be used to invoke the\ncommand, and a usage hint indicating the arguments accepted by the command.\nUsage arguments appear inside `\u003cangle-brackets\u003e`. Optional usage arguments\nappear inside square `[\u003cbrackets\u003e]`.\n\n## Abbreviating commands\n\nThe go6502 application uses a \"shortest unambiguous match\" parser to process\ncommands. This means that when entering a command, you need only type the\nsmallest number of characters that uniquely identify it.  For instance,\ninstead of typing `quit`, you can type `q` since no other commands start with\nthe letter Q.\n\nMost commands also have shortcuts. To discover a command's shortcuts, use\n`help`.\n\n## Stepping the CPU\n\nLet's use one of the `step` commands to step the CPU by a single instruction.\nType `step in`.\n\n```\n1000-   A2 EE       LDX   #$EE      A=00 X=00 Y=00 PS=[------] SP=FF PC=1000 C=0\n* step in\n1002-   A9 05       LDA   #$05      A=00 X=EE Y=00 PS=[N-----] SP=FF PC=1002 C=2\n*\n```\n\nBy typing `step in`, you are telling the emulated CPU to execute the `LDX #$EE`\ninstruction at address `1000`. This advances the program counter to `1002`,\nloads the value `EE` into the X register, and increases the CPU cycle counter\nby 2 cycles.\n\nEach time go6502 advances the program counter interactively, it disassembles\nand displays the instruction to be executed next. It also displays the current\nvalues of the CPU registers and cycle counter.\n\nThe shortcut for the `step in` command is `si`. Let's type `si 4` to step the\nCPU by 4 instructions:\n\n```\n1002-   A9 05       LDA   #$05      A=00 X=EE Y=00 PS=[N-----] SP=FF PC=1002 C=2\n* si 4\n1004-   20 19 10    JSR   $1019     A=05 X=EE Y=00 PS=[------] SP=FF PC=1004 C=4\n1019-   A9 FF       LDA   #$FF      A=05 X=EE Y=00 PS=[------] SP=FD PC=1019 C=10\n101B-   60          RTS             A=FF X=EE Y=00 PS=[N-----] SP=FD PC=101B C=12\n1007-   20 1C 10    JSR   $101C     A=FF X=EE Y=00 PS=[N-----] SP=FF PC=1007 C=18\n*\n```\n\nThis output shows that the CPU has stepped the next 4 instructions starting at\naddress `1002`.  Each executed instruction is disassembled and displayed along\nwith the CPU's register values at the start of each instruction. In this\nexample, a total of 18 CPU cycles have elapsed, and the program counter ends\nat address `1007`.  The instruction at `1007` is waiting to be executed.\n\nNote that the `step in` command stepped _into_ the `JSR $1019` subroutine call\nrather than stepping _over_ it.  If you weren't interested in stepping through\nall the code inside the subroutine, you could have used the `step over`\ncommand instead. This would have caused the debugger to invisibly execute all\ninstructions inside the subroutine, returning the prompt only after the `RTS`\ninstruction has executed.\n\nSince the CPU is about to execute another `JSR` instruction, let's try the\n`step over` command (or `s` for short).\n\n```\n1007-   20 1C 10    JSR   $101C     A=FF X=EE Y=00 PS=[N-----] SP=FF PC=1007 C=18\n* s\n100A-   20 36 10    JSR   $1036     A=00 X=EE Y=00 PS=[-Z----] SP=FF PC=100A C=70\n*\n```\n\nAfter stepping over the `JSR` call at address `1007`, all of the instructions\ninside the subroutine at `101C` have been executed, and control has returned\nat address `100A` after 52 additional CPU cycles have elapsed.\n\n## Another shortcut: Hit Enter!\n\nOne shortcut you will probably use frequently is the blank-line short cut.\nWhenever you hit the Enter key instead of typing a command, the go6502\napplication repeats the previously entered command.\n\nLet's try hitting enter twice to repeat the `step over` command two more\ntimes.\n\n```\n100A-   20 36 10    JSR   $1036     A=00 X=EE Y=00 PS=[-Z----] SP=FF PC=100A C=70\n*\n100D-   20 46 10    JSR   $1046     A=00 X=00 Y=00 PS=[-Z----] SP=FF PC=100D C=103\n*\n1010-   F0 06       BEQ   $1018     A=00 X=00 Y=00 PS=[-Z----] SP=FF PC=1010 C=136\n*\n```\n\ngo6502 has stepped over two more `JSR` instructions, elapsing another 66 CPU\ncycles and leaving the program counter at `1010`.\n\n## Disassembling code\n\nNow let's disassemble some code at the current program counter address to get\na preview of the code about to be executed.  To do this, use the `disassemble`\ncommand or its shortcut `d`.\n\n```\n* d .\n1010-   F0 06       BEQ   $1018\n1012-   A0 3B       LDY   #$3B\n1014-   A9 10       LDA   #$10\n1016-   A2 56       LDX   #$56\n1018-   00          BRK\n1019-   A9 FF       LDA   #$FF\n101B-   60          RTS\n101C-   A9 20       LDA   #$20\n101E-   A5 20       LDA   $20\n1020-   B5 20       LDA   $20,X\n*\n```\n\nNote the `.` after the `d` command.  This is shorthand for the current program\ncounter address.  You may also pass an address or mathematical expression to\ndisassemble code starting from any address:\n\n```\n* d START+2\n1002-   A9 05       LDA   #$05\n1004-   20 19 10    JSR   $1019\n1007-   20 1C 10    JSR   $101C\n100A-   20 36 10    JSR   $1036\n100D-   20 46 10    JSR   $1046\n1010-   F0 06       BEQ   $1018\n1012-   A0 3B       LDY   #$3B\n1014-   A9 10       LDA   #$10\n1016-   A2 56       LDX   #$56\n1018-   00          BRK\n*\n```\n\nBy default, go6502 disassembles 10 instructions, but you can disassemble a\ndifferent number of instructions by specifying a second argument to the\ncommand.\n\n```\n* d . 3\n1010-   F0 06       BEQ   $1018\n1012-   A0 3B       LDY   #$3B\n1014-   A9 10       LDA   #$10\n*\n```\n\nIf you hit the Enter key after using a disassemble command, go6502 will\ncontinue disassembling code from where it left off.\n\n```\n*\n1016-   A2 56       LDX   #$56\n1018-   00          BRK\n1019-   A9 FF       LDA   #$FF\n*\n```\n\nIf you don't like the number of instructions that go6502 is configured to\ndisassemble by default, you can change it with the `set` command:\n\n```\n* set DisasmLines 20\n```\n\n## Annotating code\n\nIt's often useful to annotate a line of code with a comment. I use annotations\nto leave notes to myself when I'm trying to understand how some piece of\nmachine code works.\n\nLet's consider again the code loaded by the sample script.\n\n```\n* d $1000\n1000-   A2 EE       LDX   #$EE\n1002-   A9 05       LDA   #$05\n1004-   20 19 10    JSR   $1019\n1007-   20 1C 10    JSR   $101C\n100A-   20 36 10    JSR   $1036\n100D-   20 46 10    JSR   $1046\n1010-   F0 06       BEQ   $1018\n1012-   A0 3B       LDY   #$3B\n1014-   A9 10       LDA   #$10\n1016-   A2 56       LDX   #$56\n*\n```\n\nThe `JSR` instruction at address `1007` calls a subroutine that uses all\nthe addressing mode variants of the `LDA` command.  Let's add an annotation\nto that line of code to remind ourselves later what its purpose is.\n\n```\n* annotate $1007 Use different forms of the LDA command\n*\n```\n\nNow whenever we disassemble code that includes the instruction at address\n`1007`, we will see our annotation.\n\n```\n* d $1000\n1000-   A2 EE       LDX   #$EE\n1002-   A9 05       LDA   #$05\n1004-   20 19 10    JSR   $1019\n1007-   20 1C 10    JSR   $101C     ; Use different forms of the LDA command\n100A-   20 36 10    JSR   $1036\n100D-   20 46 10    JSR   $1046\n1010-   F0 06       BEQ   $1018\n1012-   A0 3B       LDY   #$3B\n1014-   A9 10       LDA   #$10\n1016-   A2 56       LDX   #$56\n*\n```\n\nTo remove an annotation, use the `annotate` command with an address but\nwithout a description.\n\n## Dumping memory\n\nAnother common task is dumping the contents of memory.  To do this, use the\n`memory dump` command, or `m` for short.\n\n```\n* m $1000\n1000- A2 EE A9 05 20 19 10 20   \"n). ..\n1008- 1C 10 20 36 10 20 46 10   .. 6. F.\n1010- F0 06 A0 3B A9 10 A2 56   p. ;).\"V\n1018- 00 A9 FF 60 A9 20 A5 20   .).`) %\n1020- B5 20 A1 20 B1 20 AD 00   5 ! 1 -.\n1028- 02 AD 20 00 BD 00 02 B9   .- .=..9\n1030- 00 02 8D 00 03 60 A2 20   .....`\"\n1038- A6 20 B6 20 AE 00 02 AE   \u0026 6 ....\n*\n```\n\nMemory dumps include hexadecimal and ASCII representations of the dumped\nmemory, starting from the address you specified. By default, the memory\ndump shows 64 bytes, but you can specify a different number of bytes to\ndump with a second argument.\n\n```\n* m $1000 16\n1000- A2 EE A9 05 20 19 10 20   \"n). ..\n1008- 1C 10 20 36 10 20 46 10   .. 6. F.\n*\n```\n\nAs with the `disassemble` command, you can enter a blank line to continue\ndumping memory from where you left off:\n\n```\n*\n1010- F0 06 A0 3B A9 10 A2 56   p. ;).\"V\n1018- 00 A9 FF 60 A9 20 A5 20   .).`) %\n*\n1020- B5 20 A1 20 B1 20 AD 00   5 ! 1 -.\n1028- 02 AD 20 00 BD 00 02 B9   .- .=..9\n*\n```\n\nTo change the default number of bytes that are dumped by a `memory dump`\ncommand, use the `set` command:\n\n```\n* set MemDumpBytes 128\n```\n\n## Modifying memory\n\nTo change the contents of memory, use the `memory set` command, or `ms` for\nshort.\n\n```\n* ms 0x800 $5A $59 $58 $57\n* m 0x800 4\n0800- 5A 59 58 57               ZYXW\n*\n```\n\nA sequence of memory values must be separated by spaces and may include\nsimple hexadecimal values like shown in the example above, or mathematical\nexpressions like in the following:\n\n```\n* ms 0x800 12*2 'A' 1\u003c\u003c4 $0F^$05\n* m 0x800 4\n0800- 18 41 10 0A               .A..\n*\n```\n\n## Aside: Number formats\n\ngo6502 accepts numbers in multiple formats. In most of the examples we've seen\nso far, addresses and byte values have been specified in base-16 hexadecimal\nformat using the `$` prefix.\n\nThe following table lists the number-formatting options understood by go6502:\n\n Prefix   | Format      | Base | Example     | Comment\n----------|-------------|:----:|-------------|-------------------------\n _(none)_ | Decimal     | 10   | -151        | See note about hex mode.\n `$`      | Hexadecimal | 16   | `$FDED`     |\n `0x`     | Hexadecimal | 16   | `0xfded`    |\n `%`      | Binary      | 2    | `%01011010` |\n `0b`     | Binary      | 2    | `0b01011010`|\n `0d`     | Decimal     | 10   | `0d128`     | Useful in hex mode.\n\nIf you prefer to work primarily with hexadecimal numbers, you can change the\n\"hex mode\" setting using the `set` command.\n\n```\n* set HexMode true\n```\n\nIn hex mode, numeric values entered without a prefix are interpreted as\nhexadecimal values. However, because hexadecimal numbers include the letters\n`A` through `F`, the interpreter is unable to distinguish between a number and\nan identifier. So identifiers are not allowed when interpreting expressions in\nhex mode.\n\n\n## Inspecting and changing registers\n\nThe 6502 registers can be inspected using the `register` command, or `r`\nfor short.\n\n```\n* r\n1000-   A2 EE       LDX   #$EE      A=00 X=00 Y=00 PS=[------] SP=FF PC=1000 C=0\n*\n```\n\nIf you wish to change a register value, simply add additional arguments.\n\n```\n* r A $80\nRegister A set to $80.\n1000-   A2 EE       LDX   #$EE      A=80 X=00 Y=00 PS=[------] SP=FF PC=1000 C=0\n*\n```\n\nRegisters you can change this way include `A`, `X`, `Y`, `PC` and `SP`.\n\nYou can also change the CPU's status flags. Simply provide one of the flag\nnames (`N`, `Z`, `C`, `I`, `D` or `V`) instead of a register name.\n\n```\n* r Z 1\nStatus flag ZERO set to true.\n1000-   A2 EE       LDX   #$EE      A=80 X=00 Y=00 PS=[-Z----] SP=FF PC=1000 C=0\n* r Z 0\nStatus flag ZERO set to false.\n1000-   A2 EE       LDX   #$EE      A=80 X=00 Y=00 PS=[------] SP=FF PC=1000 C=0\n*\n```\n\nFurther info about the `register` command can be found by typing\n`help register`.\n\n\n## Evaluating expressions\n\nSometimes it's useful to have a calculator on hand to compute the result of a\nsimple math expression. go6502 has a built-in expression evaluator in the form\nof the `evaluate` command, or `e` for short. The evaluator understands most C\nexpression operators.\n\n```\n* e 1\u003c\u003c4\n$0010\n* e ($FF ^ $AA) | $0100\n$0155\n* e ('A' + 0x20) | 0x80\n$00E1\n* e 0b11100101\n$00E5\n* e -151\n$FF69\n```\n\nBecause go6502 is written for an 8-bit CPU with a 16-bit address space, the\nresults of all evaluations are displayed as 16-bit values.\n\n\n## Assembling source code\n\ngo6502 has a built-in cross-assembler. To assemble a file on disk into a raw\nbinary file containing 6502 machine code, use the `assemble file` command (or\n`a` for short).\n\n```\n* a sample.asm\nAssembled 'sample.asm' to 'sample.bin'.\n```\n\nThe `assemble file` command loads the specified source file, assembles it, and\nif successful outputs a raw `.bin` file containing the machine code into the\nsame directory.  It also produces a `.map` source map file, which is used to\nstore (1) the \"origin\" memory address the machine code should be loaded at,\n(2) a list of exported address identifiers, and (3) a mapping between source\ncode lines and memory addresses.\n\nOnce assembled, the binary file and its associated source map can be loaded\ninto memory using the `load` command.\n\n```\n* load sample.bin\nLoaded source map from 'sample.map'.\nLoaded 'sample.bin' to $1000..$10FF.\n```\n\n\n_To be continued..._\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeevik%2Fgo6502","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeevik%2Fgo6502","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeevik%2Fgo6502/lists"}