6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 5:12 am

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: 6502 bus tracing gadget
PostPosted: Mon Jun 08, 2015 10:57 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Here's a project to keep an eye on:
Image

It's by hoglet, and it's a bus monitor and single-stepper implemented on a GODIL, offering control and display over a serial interface and also sporting an LCD display. Presently it doesn't monitor the databus, but it uses SYNC and RDY to allow for single-stepping.

There's a link to a previous thread about debugging/single-stepping hardware, which is worth a look.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 11, 2015 6:08 pm 
Offline

Joined: Sun Jun 29, 2014 5:42 am
Posts: 352
Ed, thanks for cross-posting this here.

I've added a few more features this week:
- ability to stop the 6502 on reading a specific memory address (read breakpoints)
- ability to stop the 6502 on writing a specific memory address (write breakpoints)
- ability to set a watch on reading a specific memory address (read watches)
- ability to set a watch on writing a specific memory address (write watches)
- ability to set a watch on executing a specific instruction (instruction watches)

The watches are non-intrusive, i.e. the 6502 is not in any way interrupted. They are just logged to the serial console. To avoid loosing watch events, I've buffered these through a 512x36 FIFO in the FPGA.

The hardware currently supports 8 different addresses, with any mix of watches/breakpoints set on each address. This is controlled by a generic in the VHDL, and it could probably be increased further.

Here's an example session, setting some watches on the AtoMMC hardware registers, then and hitting break:
Code:
Atom Bus Monitor version 0.11
Compiled at 18:17:57 on Jun 11 2015
Tracing every 1 instructions while single stepping
6502 free running...
Interrupted at FE7D
>> watchw b400
Write watch set at B400
>> watchw b401
Write watch set at B401
>> watchw b402
Write watch set at B402
>> watchw b403
Write watch set at B403
>> watchr b400
Read watch, write watch set at B400
>> watchr b401
Read watch, write watch set at B401
>> watchr b402
Read watch, write watch set at B402
>> watchr b403
Read watch, write watch set at B403
>> bl
0: B400: Read watch, write watch
1: B401: Read watch, write watch
2: B402: Read watch, write watch
3: B403: Read watch, write watch
>> c
6502 free running...
Write watch hit at E09F accessing B400
Read watch hit at E0A5 accessing B400
Write watch hit at E09F accessing B400
Read watch hit at E0A5 accessing B400
Write watch hit at E0AE accessing B400
Read watch hit at E0B4 accessing B400
Write watch hit at E64F accessing B400
Read watch hit at E659 accessing B400
Read watch hit at E659 accessing B400
Read watch hit at E659 accessing B400
Write watch hit at E053 accessing B400
Read watch hit at E059 accessing B400

All of the VHDL and C code is on github, if anyone wants to take a peek:
https://github.com/hoglet67/AtomBusMon

All of this is running in a GODIL (which uses a Xilinx XC3S250E).

Dave


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 11, 2015 7:32 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Great update!


Top
 Profile  
Reply with quote  
PostPosted: Wed Jun 17, 2015 2:49 pm 
Offline

Joined: Sun Jun 29, 2014 5:42 am
Posts: 352
Hi all,

I've got a lot further with this project over the last few days.

Here's the current feature list:
- single stepping/tracing every N instructions
- instruction breakpoints (which pause the 6502)
- memory read/write breakpoints (which pause the 6502)
- instruction watches (which are non-intrusive)
- memory read/write watches (which are non-intrusive)
- a 512 word deep FIFO to allow multiple events to be queued
- two external trigger inputs, which can be used independently or can be used to make a breakpoint/watch conditional
- an AVR core running some C code to provide a command based interface over a 57600 baud serial console.

The command interface is modelled on the debugger in Atomulator, an Acorn Atom emulator written by Tom Walker.

I've also included an T65 core and changed the pinout to match the 6502, which means it's now really a full in-circuit emulator.

This allows:
- access to the 6502 registers when single stepping
- live disassembly when single stepping
- host memory read/write when the 6502 is paused
- dumping a block of memory
- disassembling a block of memory

I've successfully used this in place of the 6502 in:
- an old Atom
- a new 2015 edition Atom
- a Beeb Model B
- a Beeb Model B with a 6502 Co Pro

There's more details, including some pictures, over on Stardot thread:
http://www.stardot.org.uk/forums/viewto ... =44&t=9655

The main issue I hit on the Beeb was down to the GODIL containing 1.5K pullups to 5V, which changes the default data bus value from 0x00 to 0xFF. This confuses the OS into thinking there is a co processor attached when there isn't.

Here's it working in the Beeb:
http://stardot.org.uk/forums/viewtopic. ... 30#p114563

Dave


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 20, 2015 4:31 pm 
Offline

Joined: Sun Jun 29, 2014 5:42 am
Posts: 352
Hi all,

Here another update for anyone who is following this.

I'm pretty much feature complete now, as I've run out of code space in the AVR soft core.

Here's a picture of it installed in a Beeb in place of the 6502:
Attachment:
IMG_0975.JPG
IMG_0975.JPG [ 534.58 KiB | Viewed 2404 times ]

The serial port connect to the top left corner. The grey IDC cable is the Xilinx programmer cable, and is not needed for normal operation.

Features added over the last couple of days:
- Made the core switchable at compile time between 6502 and 65C02 (both pass the Dorman tests)
- Added address mask registers so watches/breakpoints can cover a block of addresses
- Added a 24-bit cycle counter (that is accurate even when single stepping/paused with breakpoints)
- Memory breakpoints/watches now show the data bus value
- Added a memory CRC command to test memory reads are consistent
- Added a memory test command

Here's a small demo session:
Code:
Atom Bus Monitor version 0.35
Compiled at 16:50:31 on Jun 20 2015
Tracing every 1 instructions while single stepping
6502 free running...
Interrupted
01.384661: FFC4 : JMP (0202) 
>> break ff3f
Ex Breakpoint set at FF3F
>> watchw b003
Wr watch set at B003
>> watchr b400 fffc
Rd watch set at B400
>> c
6502 free running...
Ex Breakpoint hit at FF3F
00.000002: FF3F : LDX #17     
>> s
Stepping 1 instructions
00.000004: FF41 : LDA FF9A,X 
>> s
Stepping 1 instructions
00.000008: FF44 : STA 0204,X 
>> s
Stepping 1 instructions
00.000013: FF47 : DEX         
>> s10
Stepping 10 instructions
00.000015: FF48 : BPL FF41   
00.000018: FF41 : LDA FF9A,X 
00.000022: FF44 : STA 0204,X 
00.000027: FF47 : DEX         
00.000029: FF48 : BPL FF41   
00.000032: FF41 : LDA FF9A,X 
00.000036: FF44 : STA 0204,X 
00.000041: FF47 : DEX         
00.000043: FF48 : BPL FF41   
00.000046: FF41 : LDA FF9A,X 
>> c
6502 free running...
00.000881: Wr watch hit at FF61 writing B003 = 8A
00.025938: Rd watch hit at E0AF reading B400 = 55
00.026070: Rd watch hit at E0AF reading B400 = AA
00.026201: Rd watch hit at E0C3 reading B400 = 55
00.027561: Rd watch hit at E64F reading B400 = 80
00.028846: Rd watch hit at E64F reading B400 = 80
00.030131: Rd watch hit at E64F reading B400 = 0C
00.030785: Rd watch hit at E05E reading B400 = FF
Interrupted
12.095957: FE82 : BNE FE78   
>> watchw b400 fffc
Rd watch, wr watch set at B400
>> c
6502 free running...
Ex Breakpoint hit at FF3F
00.000003: FF3F : LDX #17     
>> c
6502 free running...
00.000882: Wr watch hit at FF61 writing B003 = 8A
00.028639: Wr watch hit at E0A4 writing B400 = FE
00.028760: Rd watch hit at E0AF reading B400 = 55
00.028771: Wr watch hit at E0A4 writing B400 = FE
00.028892: Rd watch hit at E0AF reading B400 = AA
00.028902: Wr watch hit at E0B8 writing B400 = FE
00.029023: Rd watch hit at E0C3 reading B400 = 55
00.029039: Wr watch hit at E640 writing B400 = 80
00.030383: Rd watch hit at E64F reading B400 = 80
00.031668: Rd watch hit at E64F reading B400 = 80
00.032953: Rd watch hit at E64F reading B400 = 0C
00.033486: Wr watch hit at E053 writing B400 = F0
00.033607: Rd watch hit at E05E reading B400 = FF
Interrupted
12.871936: FE80 : DEY
>> crc c000 cfff
crc: D67D
>> test 2800 3bff
Memory test: Fixed 55: passed
Memory test: Fixed AA: passed
Memory test: Fixed FF: passed
Memory test: Fixed 00: passed
Memory test: Checkerboard: passed
Memory test: Inverse checkerboard: passed
Memory test: Address pattern: passed
Memory test: Inverse address pattern: passed
Memory test: Random: passed
Memory test: Random: passed
Memory test: Random: passed
>>

It's really useful being able to see the number of cycles instructions take.

There's more details, including some pictures, over on Stardot thread:
http://www.stardot.org.uk/forums/viewto ... =44&t=9655

I've also now tested it in a Superboard II, which is the only other machine I have with a socketed 6502.

Dave


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 20, 2015 7:18 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Sort of amazing that the FPGA holds both the 6502 core, and another little core which runs code also held on-chip compiled from C. It's the second core which does the disassembly and user interface over serial (if I've understood correctly)

Worth noting though, that this has grown into a 6502 socket replacement, from the original design which merely snooped the address bus and control signals (no access to the data bus)


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 20, 2015 8:04 pm 
Offline

Joined: Sun Jun 29, 2014 5:42 am
Posts: 352
BigEd wrote:
Sort of amazing that the FPGA holds both the 6502 core, and another little core which runs code also held on-chip compiled from C. It's the second core which does the disassembly and user interface over serial (if I've understood correctly)

Yes, that's exactly it.

What's surprised me is how much compiled C code you can fit in 16K of code space.

I've just optimised the disassembler a bit more and saved another few hundred bytes, so there's maybe room for one more command. All I can think of at the moment is a GO command that will set the 6502 program counter to an arbitrary address.

Dave


Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 05, 2017 5:04 pm 
Offline
User avatar

Joined: Fri Mar 31, 2017 7:52 pm
Posts: 45
This is an old thread, but BigEd pointed to the project recently. I haven't had a chance to dig through the code (and my C skills are virtually non-existent), but in addition to a GO command, the ability to remap the BRK/IRQ, Reset, and NMI vectors (basically allowing you to replace a read from ROM with a read from internal pointers) would be handy at times.

An interesting project that I want to explore more at some point...

Thanks,
Jim


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 39 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron