Page 1 of 2
How do you debug your 6502/65C02 code?
Posted: Sat Nov 27, 2021 8:11 pm
by WillisBlackburn
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.
Re: How do you debug your 6502/65C02 code?
Posted: Sat Nov 27, 2021 8:30 pm
by BigEd
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.
Re: How do you debug your 6502/65C02 code?
Posted: Sat Nov 27, 2021 10:17 pm
by drogon
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.
My "solution" may not be helpful, however with a lot of 6502 experience behind me, but not having done much for about 35 years I started from scratch with some trivial programs in assembler very bare-bones (which is what I did "back then" in 1980 or so). Write a loop, check with a 'scope, then get an LED blinking and take it from there. I was bringing up new hardware at the same time, so doubly challenging.
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
Re: How do you debug your 6502/65C02 code?
Posted: Sat Nov 27, 2021 10:39 pm
by GARTHWILSON
How do you debug your 6502/65C02 code?
http://wilsonminesco.com/6502primer/debug.html
(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 .
Re: How do you debug your 6502/65C02 code?
Posted: Sat Nov 27, 2021 10:44 pm
by barrym95838
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.
That's how I got my VTL02 interpreter working (at ~1KB of dense machine code, my largest hobby software project to date). Most problems seemed to boil down to off-by-ones and errant INYs and DEYs, which updated the text offset pointer. The interpreter itself was of no help, since the concept of an error is completely foreign to it, a situation that I may rectify when I eventually get a VTLC02 version completed and integrated with my still-unfinished HEGEMON 65c02 debugger/monitor/mini-assembler/disassembler, all in a ROMable ~2.5KB package.
Re: How do you debug your 6502/65C02 code?
Posted: Sun Nov 28, 2021 12:03 am
by IamRob
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.
Re: How do you debug your 6502/65C02 code?
Posted: Sun Nov 28, 2021 12:13 am
by Martin_H
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?
Posted: Sun Nov 28, 2021 8:21 am
by BigEd
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/
Re: How do you debug your 6502/65C02 code?
Posted: Sun Nov 28, 2021 5:05 pm
by floobydust
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.
Re: How do you debug your 6502/65C02 code?
Posted: Sun Nov 28, 2021 10:50 pm
by Proxy
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.
Re: How do you debug your 6502/65C02 code?
Posted: Mon Nov 29, 2021 1:35 pm
by vbc
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.
For development of vbcc (debugging and automated tests), I use a modified version of an emulator written by Frank Wille a long time ago. It is written in portable C and provides the option to write plugins for GUIs and peripherals. I added a simple text-based user-interface (the original contained a GUI for the Amiga) with debug-features like single-step, go-to-next, go-to-address, disassemble or set-breakpoint.
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?
Posted: Mon Nov 29, 2021 1:55 pm
by BillG
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.
Re: How do you debug your 6502/65C02 code?
Posted: Mon Nov 29, 2021 8:20 pm
by BigDumbDinosaur
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.
Re: How do you debug your 6502/65C02 code?
Posted: Mon Nov 29, 2021 9:51 pm
by MicroCoreLabs
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.
Re: How do you debug your 6502/65C02 code?
Posted: Tue Nov 30, 2021 12:19 am
by Druzyek
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.