How do you debug your 6502/65C02 code?
-
WillisBlackburn
- Posts: 51
- Joined: 14 Aug 2021
How do you debug your 6502/65C02 code?
I'm using cc65 and the included ca65 assembler. I'm having a hard time debugging code I've written and am surprised by the lack of tools; I feel like I must be missing something obvious. I'm wondering how other people deal with this.
Some background. I'm writing code for my own 6502 board, and it's actually a 65C02, so my code has some 65C02-specific instructions here and there. I've written unit tests that I run with the sim65 emulator that's part of the cc65 package. But sometimes (usually?) the tests just crash the simulator when they don't work, and it's hard for me to figure out what's going on.
I tried using VICE, but apparently it doesn't support the 65C02. In general, tools that are intended for C64 and Atari development tend to have this problem.
I'm kind of wondering why sim65 doesn't support debugging. It is obviously emulating the CPU and the cc65 package includes a disassembler, so seems like it would be straightforward to put the pieces together.
If you have a solution that works for you, please let me know.
Some background. I'm writing code for my own 6502 board, and it's actually a 65C02, so my code has some 65C02-specific instructions here and there. I've written unit tests that I run with the sim65 emulator that's part of the cc65 package. But sometimes (usually?) the tests just crash the simulator when they don't work, and it's hard for me to figure out what's going on.
I tried using VICE, but apparently it doesn't support the 65C02. In general, tools that are intended for C64 and Atari development tend to have this problem.
I'm kind of wondering why sim65 doesn't support debugging. It is obviously emulating the CPU and the cc65 package includes a disassembler, so seems like it would be straightforward to put the pieces together.
If you have a solution that works for you, please let me know.
Re: How do you debug your 6502/65C02 code?
It's not good if sim65 crashes - or does that just mean that your program has gone into the weeds and the sim65 is continuing to operate, but not usefully to you?
If you can get the simulator to report a trace of the program counter, or the instruction-by-instruction machine state, that can be very helpful. Even for moderately long-running programs, an editor can cope with a very large log file these days.
Adding instrumentation to your code can help: did it reach this point? this point? this point? That could be a case of adding a BRK. Expect to run the code over and over, learning a little each time.
Perhaps you can load up a suitable monitor into the emulated environment - one which can single step.
In the end, if you're relatively new to 6502 land, you will be simulating in your head or on paper, figuring out the register changes as you go round a loop.
If you can get the simulator to report a trace of the program counter, or the instruction-by-instruction machine state, that can be very helpful. Even for moderately long-running programs, an editor can cope with a very large log file these days.
Adding instrumentation to your code can help: did it reach this point? this point? this point? That could be a case of adding a BRK. Expect to run the code over and over, learning a little each time.
Perhaps you can load up a suitable monitor into the emulated environment - one which can single step.
In the end, if you're relatively new to 6502 land, you will be simulating in your head or on paper, figuring out the register changes as you go round a loop.
Re: How do you debug your 6502/65C02 code?
WillisBlackburn wrote:
I'm using cc65 and the included ca65 assembler. I'm having a hard time debugging code I've written and am surprised by the lack of tools; I feel like I must be missing something obvious. I'm wondering how other people deal with this.
Once I knew I could light an LED I could implement print character, then string, then numbers and so on. Today, printf is my debugger but while my RubyOS can dump memory (and disassemble). It's not a "monitor" as such though.
Not helpful if starting the debugger is your normal way of working though - it's a very different world.
I did use the symon emulator very briefly though but it's memory map wasn't what I was after in my target.
but once I could run some simple asm programs (I used ca65 to assemble them) I moved on to writing my own monitor, then OS, then I created a cc65 target for my system. That was relatively easy, but that was also after I had a good enough operating system to run EhBASIC and BBC Basic.
Good luck with the route you take, but I'd strongly suggest starting with blinking an LED.
Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: How do you debug your 6502/65C02 code?
Quote:
How do you debug your 6502/65C02 code?
(Do go through the whole 6502 primer though. It's in 22 logically organized pages, and was written to answer questions and problems that kept coming up on the forum. The primer is continually getting updated.) I should probably add a couple of paragraphs, with diagrams, about using as little as a single VIA pin to output status in serial which you can watch on the oscilloscope, as I mentioned at viewtopic.php?p=88499#p88499 .
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: How do you debug your 6502/65C02 code?
BigEd wrote:
Adding instrumentation to your code can help: did it reach this point? this point? this point? That could be a case of adding a BRK. Expect to run the code over and over, learning a little each time.
Last edited by barrym95838 on Mon Nov 29, 2021 1:25 am, edited 1 time in total.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
Re: How do you debug your 6502/65C02 code?
The fastest way for me is not from the assembler, but from the ML code listing itself. I change each JSR to a JMP, and then call each subroutine separately until I find the culprit causing the crash. Usually can find the routine that causes the crash within a half dozen tries. After that I quickly scan the code to make sure the branches are not branching to the middle of another instruction, which is usually the case, or if something is pushed on the stack to make sure it gets pulled off.
Very rarely do programs crash due to some erroneous value in one of the registers. But I do have a "BETTER.BRK" (better break) that shows all the values of all the registers,including the processor register, wherever the BRK instruction is inserted. I rarely use it though as it becomes more time consuming to figure out where to insert the BRK. The first method works way faster for me.
Very rarely do programs crash due to some erroneous value in one of the registers. But I do have a "BETTER.BRK" (better break) that shows all the values of all the registers,including the processor register, wherever the BRK instruction is inserted. I rarely use it though as it becomes more time consuming to figure out where to insert the BRK. The first method works way faster for me.
Re: How do you debug your 6502/65C02 code?
I break code into modules, write a test harnesses to run it under Py65mon. The test harness uses print statements to indicate pass or fail of each test. After I am fairly certain it works I will run it on real hardware.
Re: How do you debug your 6502/65C02 code?
Oh, py65mon - good thought! It's very like the kind of machine monitor you'd run on the machine, and of course you can tweak it if you need to.
https://github.com/mnaberez/py65#monitor
https://py65.readthedocs.io/en/latest/
https://github.com/mnaberez/py65#monitor
https://py65.readthedocs.io/en/latest/
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: How do you debug your 6502/65C02 code?
Whenever I have a coding problem, I first try to isolate anything I've done which might be wrong, then examine in a larger context of how the failure is happening. My Monitor code has the ability to call a routine and also load the registers with user data before calling the routine. It then captures the register data on return and I can display it.
In other cases, I'll use a BRK instruction at certain code points. My Monitor also captures the BRK instruction, so I can get register data and also use a BRK signature byte if I'm using more than a single BRK in the code. This certainly helps... but debugging can be tricky, depending on what's going on.
Having a mix of routines that interact with an interrupt service routine can also be tricky to debug, especially if there are multiple paths and routines in the ISR. In some worse case scenarios, it might require using a logic analyzer to get a better view what the hardware is actually doing, versus what you think it should be doing based on the code you're running.
In other cases, I'll use a BRK instruction at certain code points. My Monitor also captures the BRK instruction, so I can get register data and also use a BRK signature byte if I'm using more than a single BRK in the code. This certainly helps... but debugging can be tricky, depending on what's going on.
Having a mix of routines that interact with an interrupt service routine can also be tricky to debug, especially if there are multiple paths and routines in the ISR. In some worse case scenarios, it might require using a logic analyzer to get a better view what the hardware is actually doing, versus what you think it should be doing based on the code you're running.
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: How do you debug your 6502/65C02 code?
to be honest i just do the same thing i do in any programming language, use print statements to see if the code reaches a certain point and print out any variable i might be able to check.
like if i know that after function xyz the variable "num" is supposed to be equal to something specific like "204" for example i can just have the system print it out so i can manually check it after running it.
so far it worked pretty well but it's obviously not ideal compared to an NMI-Button powered Memory Monitor or similar debugging tool.
like if i know that after function xyz the variable "num" is supposed to be equal to something specific like "204" for example i can just have the system print it out so i can manually check it after running it.
so far it worked pretty well but it's obviously not ideal compared to an NMI-Button powered Memory Monitor or similar debugging tool.
Re: How do you debug your 6502/65C02 code?
WillisBlackburn wrote:
I'm using cc65 and the included ca65 assembler. I'm having a hard time debugging code I've written and am surprised by the lack of tools; I feel like I must be missing something obvious. I'm wondering how other people deal with this.
Some background. I'm writing code for my own 6502 board, and it's actually a 65C02, so my code has some 65C02-specific instructions here and there. I've written unit tests that I run with the sim65 emulator that's part of the cc65 package. But sometimes (usually?) the tests just crash the simulator when they don't work, and it's hard for me to figure out what's going on.
I tried using VICE, but apparently it doesn't support the 65C02. In general, tools that are intended for C64 and Atari development tend to have this problem.
I'm kind of wondering why sim65 doesn't support debugging. It is obviously emulating the CPU and the cc65 package includes a disassembler, so seems like it would be straightforward to put the pieces together.
If you have a solution that works for you, please let me know.
Some background. I'm writing code for my own 6502 board, and it's actually a 65C02, so my code has some 65C02-specific instructions here and there. I've written unit tests that I run with the sim65 emulator that's part of the cc65 package. But sometimes (usually?) the tests just crash the simulator when they don't work, and it's hard for me to figure out what's going on.
I tried using VICE, but apparently it doesn't support the 65C02. In general, tools that are intended for C64 and Atari development tend to have this problem.
I'm kind of wondering why sim65 doesn't support debugging. It is obviously emulating the CPU and the cc65 package includes a disassembler, so seems like it would be straightforward to put the pieces together.
If you have a solution that works for you, please let me know.
Originally, it only supported the 6502, but I added some support for 65c02 (at least those instructions generated by vbcc).
There is not much documentation and I think Frank probably never released this tool, but if there is some demand I can ask him about that.
Re: How do you debug your 6502/65C02 code?
I do my debugging in my own homegrown simulator/debugger. It is patterned after DEBUG or SYMDEB and supports stepping and breakpoints.
It counts the clock cycles used by instructions so I use it to compare snippets of code for efficiency. It also has what I call a "clock breakpoint" so that if code runs away, I can have the debugger stop after N cycles. Not as useful in general as instruction trace logging, but it does not take added time or storage.
Potential enhancements in the future may include memory read or write breakpoints, symbolic debugging or some kind of GUI/CUI interface.
It counts the clock cycles used by instructions so I use it to compare snippets of code for efficiency. It also has what I call a "clock breakpoint" so that if code runs away, I can have the debugger stop after N cycles. Not as useful in general as instruction trace logging, but it does not take added time or storage.
Potential enhancements in the future may include memory read or write breakpoints, symbolic debugging or some kind of GUI/CUI interface.
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: How do you debug your 6502/65C02 code?
I do it the old-fashioned way: with a machine language monitor, breaks in the code at the areas where there is, or might be trouble, and a good understanding of what the program is supposed to do.
Last edited by BigDumbDinosaur on Tue Nov 30, 2021 8:09 am, edited 1 time in total.
x86? We ain't got no x86. We don't NEED no stinking x86!
-
MicroCoreLabs
- Posts: 62
- Joined: 05 Oct 2017
Re: How do you debug your 6502/65C02 code?
One option could be to add some printf's to both my emulator code and yours to output an opcode sequence number, the PC and opcode, and the state of the registers. Both of our emulators should execute addresses and opcodes in lockstep so you could use the traces to see where our emulators begin to diverge.
https://github.com/MicroCoreLabs/Projec ... /MCL65.ino
I was recently considering posting the command-line version of my code which replaces the 6502 bus interface with a generic ram_array for the RAM/ROM, along with the version of Klaus's opcode tests. This is the method I used to develop my emulator where subtle differences caused a divergence which allowed me to quickly focus on the error.
https://github.com/MicroCoreLabs/Projec ... /MCL65.ino
I was recently considering posting the command-line version of my code which replaces the 6502 bus interface with a generic ram_array for the RAM/ROM, along with the version of Klaus's opcode tests. This is the method I used to develop my emulator where subtle differences caused a divergence which allowed me to quickly focus on the error.
Re: How do you debug your 6502/65C02 code?
Everyone has posted good options for debugging, and I'll add what I use. My emulator works in JavaScript so you can run it in your browser. Here's an example on my website. If you click on "System Information" you can see all the registers and single step the processor. It shows several panes of memory and highlights the instruction executed and any memory accessed which has come in really handy. It can load a listing from CA65 and highlight each line of source when you single step. You can also see the entire memory contents and log all registers on each cycle. It supports bank switching and has 32k of RAM mapped one byte per pixel to a 128x64 screen. I've been able to get EhBASIC and TaliForth 2 running on it.
You can download the source from github and run it locally. I have a line in my script that copies the binary and listing to the emulator folder every time I run CA65. I'm happy to help if you want to get it running.
You can download the source from github and run it locally. I have a line in my script that copies the binary and listing to the emulator folder every time I run CA65. I'm happy to help if you want to get it running.