How do you debug your 6502/65C02 code?

Programming the 6502 microprocessor and its relatives in assembly and other languages.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: How do you debug your 6502/65C02 code?

Post by GARTHWILSON »

I've used various ones of the ideas posted above. I just added the following to the "65816 EMU Pin and WS2812B Digital LEDs" topic. I got the idea from one of the electronic industry magazines' "Ideas for design" sections.
--------------------------------------------------
Here's a diagram to add to my post above, about using as little as a single pin to output status bytes from a microcontroller with extremely limited I/O. The pin could even be one that's being used for something else as long as you can let it go for short periods for the purpose. For example, you might have the pin driving an indicator LED and it won't hurt anything to have if flicker when you're outputting data during development; or even a pushbutton input, as long as you don't need to push the button while you're outputting the data. I've done this with PICs having as few as 8 pins (the PIC12's). There are others even in SOT-23 packages with only 5 or 6 pins [power, ground, and 3 or 4 I/O pins] (although I have not used those, so far). This is copy-and-pasted from the comments in the source code for a work project I did a few years ago. The clock speed is not important, only the relative lengths of the high and low pulses.

Code: Select all

;             ┌───────────────────────────────────────────────╖
;             │      OUTPUT STATUS  (for troubleshooting)     ║
;             ╘═══════════════════════════════════════════════╝
;
; This status reporting is only for debugging.  It's not needed in the production units.
; Reporting by serial bit stream will be on PC4.  We'll start with a 1.5ms high pulse as a start bit, followed by a 1.5ms low
;   time, and then each 0 after that will be .5ms hi + 1ms lo, and each 1 will be 1ms hi + .5ms lo, so a bit starts every 1.5ms,
;   on a schedule.  There's an extra 1.5ms low time between bytes.  Interrupts will need to be turned off temporarily to avoid
;   jitter that would make it difficult to see the pattern repeating on an analog 'scope, as well as making sure short pulses
;   don't get too long.
; To make it easier to see where the start bit of a multi-byte report is with a dual-trace 'scope, PC3 (pin 14) is pulsed low.
;
;
;      low 1.5ms to make        Start     then  ┌────────── example 01001011, or $4B ──────────┐      ┌── start next byte
;      start bit visible─┐      1.5ms     1.5ms
;                        │       high      low    0     1     0     0     1     0     1     1           0     0
;             ───────┐   V    ┌────────┐        ┌─┐   ┌───┐ ┌─┐   ┌─┐   ┌───┐ ┌─┐   ┌───┐ ┌───┐       ┌─┐   ┌─┐   ┌─ . . .
; (PC4 pin 15)───────┴────────┘        └────────┘ └───┘   └─┘ └───┘ └───┘   └─┘ └───┘   └─┘   └───────┘ └───┘ └───┘
;
; (PC3 pin 14)────────────────┐        ┌─────────────────────────────────────────────────────────────────────────────────────────
; (for triggering)            └────────┘
;                                                                                               └──┬──┘
;                             └────────┬───────┘                                                   │
;                                      └─start bit                     1.5ms extra between bytes───┘
;
;
; Since it is not always desirable for the the status report to run every time OUTPUT_STATUS is encountered in the program, it
;   will look at PC5, pin 16, which has a passive pull-up.  If the switch to ground is open, it won't report.
; If you want it to keep reporting continually, you'll have to call it from a loop.
; Byte at RAM address REPORT_ARRAY is sent first.  Bytes are sent msb-first.
; To use OUTPUT_STATUS, put the bytes you want to output in REPORT_ARRAY, and put the number of bytes to report in REPORT_COUNT.
;   REPORT_COUNT will get decremented to 0 during the reporting, so the program must re-initialize it before each call.
; ══════════ NOTE !! If you call OUTPUT_STATUS repeatedly in a loop, you must re-init REPORT_COUNT every time! ══════════

I'll leave the actual program code out since it's not 65xx, unless someone asks for it. It's in PIC assembly language with a lot of macros.
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?
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: How do you debug your 6502/65C02 code?

Post by BigEd »

That's really nice! I like the view of various memory areas of interest. Here's an illustrative screen grab (it's in-browser so very easy to increase the font size)
Attachments
calc6502-sysinfo.png
User avatar
Druzyek
Posts: 367
Joined: 12 May 2014
Contact:

Re: How do you debug your 6502/65C02 code?

Post by Druzyek »

Thanks, BigEd. What browser are you using? The gray and white rows should be aligned straight...
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: How do you debug your 6502/65C02 code?

Post by BigEd »

It's Chrome - very ordinary choice!
MicroCoreLabs
Posts: 62
Joined: 05 Oct 2017

Re: How do you debug your 6502/65C02 code?

Post by MicroCoreLabs »

Safari also misaligned
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: How do you debug your 6502/65C02 code?

Post by drogon »

Druzyek wrote:
Thanks, BigEd. What browser are you using? The gray and white rows should be aligned straight...
My guess is that it's to do with the font - proportional width vs. fixed width font - likely in the original page on the server that page comes from (all I see is a static image here, so the image is as Ed saw it in his browser).

Maybe force a fixed-width font (or pre-formatted text tags?) in the javascript?

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
User avatar
Druzyek
Posts: 367
Joined: 12 May 2014
Contact:

Re: How do you debug your 6502/65C02 code?

Post by Druzyek »

Below is what I see accessing the website from Windows. The problem is that I use the font Lucida Console all over the site which has been my goto fixed width font since the earlier 2000s. Apparently, it was designed for situations exactly like this where you need to cram a lot of text into a small area and have it be legible. It turns out that the font comes with Windows but not everyone else has it. The website is updated now to use Courier New as a fallback then whatever your monospace font is if you don't have that. Would you guys mind having a look again? I should stick to embedded programming and stop pretending to be a web developer...
Attachments
lucida_console.PNG
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: How do you debug your 6502/65C02 code?

Post by drogon »

Druzyek wrote:
Below is what I see accessing the website from Windows. The problem is that I use the font Lucida Console all over the site which has been my goto fixed width font since the earlier 2000s. Apparently, it was designed for situations exactly like this where you need to cram a lot of text into a small area and have it be legible. It turns out that the font comes with Windows but not everyone else has it. The website is updated now to use Courier New as a fallback then whatever your monospace font is if you don't have that. Would you guys mind having a look again? I should stick to embedded programming and stop pretending to be a web developer...
It's still a bit wonky for me. I even tried changing the font to courrier-10 and telling my browser (firefox) to use my fonts all the time. I tried with chrome too. Same. Example here:
Screenshot_2021-12-11_08-46-03.png
Can you use <pre>...</pre> tags?

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
rwiker
Posts: 294
Joined: 03 Mar 2011

Re: How do you debug your 6502/65C02 code?

Post by rwiker »

I think the easiest solution is only set font-family or font in one place, that being for "body" in either main.css or emu6502.css. I just did that, and got a clean-looking result with a "font-family" setting of (just) "courier". A more useful setting might be

Code: Select all

font-family: Monaco, Lucida Sans Typewriter, Courier;
User avatar
Druzyek
Posts: 367
Joined: 12 May 2014
Contact:

Re: How do you debug your 6502/65C02 code?

Post by Druzyek »

drogon wrote:
It's still a bit wonky for me. I even tried changing the font to courrier-10 and telling my browser (firefox) to use my fonts all the time. I tried with chrome too. Same. Example here:
Thanks, Gordon. Strange. The font in your screenshot is not a monospace font, although Courier and Courier New both should be. You can see on the left side that the letters in Dx, Ex, and Fx on the left side are not monospaced.
Quote:
Can you use <pre>...</pre> tags?
Hmm, that should set the text to whatever your browser uses when you set the font to "monospace." I think setting the CSS to monospace would achieve the same thing, but I wouldn't be able to control which font it chooses for that.
Quote:
I think the easiest solution is only set font-family or font in one place, that being for "body" in either main.css or emu6502.css. I just did that, and got a clean-looking result with a "font-family" setting of (just) "courier".
Ya that would work though I like having a normal font for text and only using something like Courier for numbers or code examples. You can see if you click on Emulator information that there is a good amount of text there.
User avatar
Druzyek
Posts: 367
Joined: 12 May 2014
Contact:

Re: How do you debug your 6502/65C02 code?

Post by Druzyek »

Ok, it should be updated now. I had uploaded the updated version to the wrong place on the website...

Thanks everyone for the help.
WillisBlackburn
Posts: 50
Joined: 14 Aug 2021

Re: How do you debug your 6502/65C02 code?

Post by WillisBlackburn »

Here's what I wound up doing.

I defined a macro that inserts a BRK followed by a data byte into the code:

Code: Select all

.macro  debug   value
        brk
        .byte   value
.endmacro
then I pointed the BRK vector at $FFFE to a handler that calls fprintf to print the values of all the registers to stderr. I save all the cc65 zero page registers, since I use them in my assembly code too.

Code: Select all

.include "zeropage.inc"
.import _fprintf, _stderr

.zeropage

save_pc: .res 2

.bss

save_a: .res 1
save_x: .res 1
save_y: .res 1
save_sp: .res 1
save_cc65_regs: .res zpsavespace

.code

format: .byte "$%02X: A=%02X X=%02X Y=%02X SP=%02X", $0A, $00

; Prints the register values to stderr.

debug_handler:
        cld                     ; Clear decimal flag (just in case)
        sta     save_a          ; Save 6502 registers
        stx     save_x
        sty     save_y
        tsx                     ; Get stack pointer into X
        stx     save_sp         ; Save it so we can print it
        ldy     $102,x          ; PC low byte
        sty     save_pc
        ldy     $103,x          ; PC high byte
        dey                     ; Subtract 256 from PC; we will index with Y = 255 to get PC-1
        sty     save_pc+1
        ldx     #0              ; Prepare to save cc65 registers
@save_reg:
        lda     sp,x            ; sp is the first register
        sta     save_cc65_regs,x
        inx
        cpx     zpsavespace
        bne     @save_reg 
        lda     _stderr         ; fprintf(stderr, ...
        ldx     _stderr+1
        jsr     pushax
        lda     #<format        ; format, ...
        ldx     #>format
        jsr     pushax
        ldy     #$FF
        lda     (save_pc),y     ; id, ...
        jsr     pusha0          
        lda     save_a          ; A, ...
        jsr     pusha0
        lda     save_x          ; X, ...
        jsr     pusha0
        lda     save_y          ; Y, ...
        jsr     pusha0
        lda     save_sp         ; SP)
        jsr     pusha0
        ldy     #14             ; 14 bytes on the C stack
        jsr     _fprintf
        ldx     #0              ; Prepare to restore cc65 registers
@restore_reg:
        lda     save_cc65_regs,x
        sta     sp,x      
        inx
        cpx     zpsavespace
        bne     @restore_reg 
        lda     save_a          ; Restore 6502 registers
        ldx     save_x
        ldy     save_y
        rti


Then I just sprinkle the debug macro around problem parts of the code so I can see what's going on. Using BRK is nice because it's only 2 bytes (so less likely that the presence of the debug line will cause some branch to go out of range) and because I can stuff the extra value after the BRK, which I print along with the register values so I can tell which debug line generated the output.
pzembrod
Posts: 22
Joined: 05 Sep 2020
Contact:

Re: How do you debug your 6502/65C02 code?

Post by pzembrod »

WillisBlackburn wrote:
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.
You could use x16emu (https://www.commanderx16.com/forum/inde ... nmaclinux/), the emulator for thee Commander X16, which has a 65C02 CPU. I'm using both VICE and x16emu to test the library for cc64 which runs on both C64/C16 and X16.
Post Reply