Open Source Logic Analyzer Experiments

for bbc micro/electron hardware, peripherals & programming issues (NOT emulators!)
Post Reply
User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Open Source Logic Analyzer Experiments

Post by hoglet » Sat Oct 14, 2017 11:17 am

Morning all,

This thread is all about using Logic Analyzers to debug 6502 based systems.

I'll break it into several parts to make it manageable, and so I don't hit forum image limits.

Part 1: An Introduction to Sigrok and Logic Sniffer

Over the last couple of days, with some help from BigEd, I've been exploring the boundaries of what can be done with cheap logic analyzers. The idea is to make these more useful as diagnostic tools for 6502-based machines.

I've settled on sigrok as a software stack for several reasons:
- it's open source
- it's being actively developed
- it's multi-platform (Linux, Mac OS X, Windows, FreeBSD, OpenBSD, NetBSD, Android)
- it has a long list of supported hardware
- it has a very modular architecture
- it deals efficiently with very large capture files

The architecture is very clean:
- all the device specific functionality is encapsulated in a back end library (libsikgok)
- there is a command line based application called sigrok-cli
- there is GUI based application called pulseview
- it already contains a large number of stackable protocol decoders
- it allows custom protocol decoders to be written in python

What's really nice is that as you extend its capabilities, those capabilities become visible to the applications without needing to recompile the applications. This allows you to add a new protocol decoder or extend a backend device driver with the minimum of fuss.

Anyway, a couple of days ago I started playing around with a logic analyzer called the Open Bench Logic Sniffer. This was developer about 8 years ago as an open source collaboration between Jack Gassett (Gadget Factory) and Dangerous Prototypes.

This is the original hardware:
Openbench_logic_sniffer_front.png
I think a few forum members own these, and they are still available from seedstudio for about $50.

Now, I unfortunately I don't have one of these, but I do own a Papilio One, and it's easy to recompile the Logic Sniffer design for that hardware:
IMG_1121.JPG
I've put the latest design files for this in a github project:
https://github.com/hoglet67/Papilio_One_OLS

I should say up front that this is not the hardware I would recommend people buy, primarily because the capture depth is quite poor (12,288 samples at 16 bits wide). But it's what I had to hand, and it will be sufficient to do some useful work on.

Here's a picture of it connected to my Master 128:
IMG_1122.JPG
to be continued....
Last edited by hoglet on Sat Oct 14, 2017 2:37 pm, edited 4 times in total.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sat Oct 14, 2017 11:18 am

Part 2: Probing the 6502 with Sigrok

I've connected the following wires up to the 6502 on my Master 128:
- D0..D7
- RnW
- Sync
- Rdy
- Phi2
- IRQn
- NMIn
- RSTn

That's a total of 15, plus a ground, so there is just one spare.

I should say that the Open Bench Logic Sniffer supports 32 channels, but most cheap logic analyzers only have 16 channels, so I wanted to see how useful these are. Crucially, this does not allow the address bus to be captured.

Let's start by using the PulseView application, which is run with:

Code: Select all

pulseview --driver ols:conn=/dev/ttyUSB1:serialcomm=921600/8n1
Note: the device file and speed will likely be different on your system. I've also boosted the speed of my logic sniffer from 115200 to 921600 baud. This might be harder to do with the original hardware, as that uses a PIC for the serial communications.

In PulseView select the Open Logic Sniffer device, rename the inputs to something more meaningful, and disable any unused ones (to save capture memory).

Next, you need to configure a capture clock. In an ideal world you would use Phi2 as an external capture clock, and later I'll talk about how to do that. But that feature (external clocking) is not yet available in the Open Logic Sniffer sigrok driver. So instead we'll use an internal clock, and make sure this is quite a bit faster than the 2MHz speed of the 6502. I've chosen to use 10MHz.

Hit run and you should see something like:
sigrok1.png
Now there are a few things to note:
- we seem to have captured an interrupt happening
- during the interrupt handler is seems the RDY signal is used to insert wait states, rather than stretching the clock as the Model B does
- the duration of the capture is only 1.28ms

The reason for the short capture is that the Logic Sniffer uses FPGA block RAM as it's only buffer. This allows it to do fast captures, but there isn't much block RAM. That weakness that can be mitigated a bit if you can set an appropriate trigger. I have a couple of thought on how to overcome this, but both involve using different hardware:
- extend the Logic Sniffer to buffer to external DRAM - someone has already done this on a different FPGA board called the Pipistrello (see here). But that board has just been discontinued. So I'm thinking of porting this work to another board, such as the $50 Numato Mimas V2
- use a streaming logic analyzer that uses memory in the host. I've just ordered one of these to experiment with.

Anyway, back to Pulse View. Let's zoom in and look at the interrupt happening:
sigrok2.png
If you look carefully, each sample is represented by a small dot. So in one clock cycle of Phi2 there are 5 samples (one every 100ns).

But it's still quite hard to see what's going on, and that's where protocol decoders come in.

One of the simplest Protocol decoders is called the Parallel decoder. This will sample a parallel bus on a specified clock edge:
sigrok3.png
The region I have highlighted is start of the Master's interrupt handler:

Code: Select all

.irqbrk
E59E  85 FC              ..      STA &FC
E5A0  68                 h       PLA
E5A1  48                 H       PHA
E5A2  29 10              ).      AND #&10
E5A4  D0 03              ..      BNE &E5A9
E5A6  6C 04 02           l..     JMP (&0204)
And if you look just before the highlighted region, you can see the interrupt vector &E5, &9E being fetched. But honestly, even with Parallel bus decoding it's really hard to see what's happening.

What's really needed is a Protocol Decoder that understands the 6502...

to be continued...
Last edited by hoglet on Sat Oct 14, 2017 2:44 pm, edited 9 times in total.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sat Oct 14, 2017 11:18 am

Part 3: Writing a 6502 Protocol Decoder

A protocol decoder in sigrok transforms data from one representation to another (usually higher) representation.

A good example of this is decoding the SPI serial bus:
Pd_spi_example.png
In the above, the line labelled SPI at the top is the higher level representation being generated by the SPI protocol decoder.

SIgrok lets you write protocol decoder's in python, and there are a couple of useful documents to get you started:
- https://sigrok.org/wiki/Protocol_decoder_HOWTO
- https://sigrok.org/wiki/Protocol_decoder_API

What we (myself and BidEd) have been trying to do is to write a protocol decoder that consumes the 6502 data and control signals, and gives a higher level view of the 6502 bus cycles and the instructions being executed. A bit like a disassembler does, but running on live bus data.

Now, I should confess that this is the first time I have written any python, so apologies if there are silly mistakes.

There are two parts to our protocol decoder:
- a table of data describing the 6502 instruction set: table.py
- the protocol decoder itself: pd.py

So what does this give you? Let's add it in to PulseView and see:
sigrok4.png
There are now three rows:
- the data bus (as a hex value)
- the 6502 cycle type
- the 6502 instruction disassembly

If you Zoom in a little, you can see the different 6502 cycles being annotated:
sigrok5.png
The 6502 cycle types are:
- Fetch (i.e. the first byte of an instruction)
- Op1 (i.e. the second byte of an instruction)
- Op2 (i.e. the third byte of an instruction)
- Read (a memory read)
- Write (a memory write)

A couple of other noteworthy features (both due to BigEd's knowledge of the 6502):
- It's possible to recognise the start of a 6502 interrupt cycle because of the three consecutive writes.
- It's possible to predict the value of the PC even though the address bus is not connected.

The code for this is a little hairy, but seems to work very reliably:

Code: Select all

                # Look for control flow changes and update the PC
                if opcode == 0x40 or opcode == 0x00 or opcode == 0x6c or opcode == 0x7c or write_count == 3:
                    # RTI, BRK, INTR, JMP (ind), JMP (ind, X)
                    pc = (next_pc >> 8) & 0xffff
                elif opcode == 0x20 or opcode == 0x4c:
                    # JSR abs, JMP abs
                    pc = op2 << 8 | op1
                elif opcode == 0x60:
                    # RTS
                    pc = (next_pc + 1) & 0xffff
                elif pc < 0:
                    # PC value is not known yet, everything below this point is relative
                    pc = -1
                elif opcode == 0x80:
                    # BRA
                    pc += signed_byte(op1) + 2
                elif (opcode & 0x0f) == 0x0f and cyclenum - last_sync_cyclenum != 2:
                    # BBR/BBS
                    pc += signed_byte(op2) + 2
                elif (opcode & 0x1f) == 0x10 and cyclenum - last_sync_cyclenum != 2:
                    # BXX: op1 if taken
                    pc += signed_byte(op1) + 2
                else:
                    # Otherwise, increment pc by length of instuction
                    pc += len
Here's a final example, this time using reset as a trigger:
sigrok6.png
You can see that the 6502 handles reset very much like an interrupt.

You can also see here the Master using RDY to insert wait states in the "STA FE8E" instruction rather than cycle stretching.

(to be continued)
Last edited by hoglet on Sat Oct 14, 2017 2:48 pm, edited 5 times in total.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sat Oct 14, 2017 11:18 am

Part 4: Synchronous capture, triggers and sigrok-cli

I've already noted that capture memory in the current Logic Sniffer is very limited. When sampling 16 channels, the maximum capture depth is 12,288 samples. It turns out this is only about 680 instructions.

So how can we capture more data with Logic Sniffer?
- add more memory - not an option with my current hardware
- enable the run length encoding feature - I tried and it doesn't seem to work properly
- enable the synchronous capture feature (using Phi2 as the external capture clock)
- use triggers (to capture the data we want)

Although the latest Logic Sniffer design (called the Demon Core) has these features, they have not been included in the current Sigrok driver. But because Sigrok (as a platform) already supports them, adding them in to a specific driver is not very much work so I had a go. My changes to libsigrok are in github here:

Code: Select all

718357b1f ols: add a config getter/setter for noise filter
3a191e21c ols: Allow specification of external clock edge
2520bf232 ols: merged trigger disable code from pipistrello-ols (for 3.08 demon core)
0ef99558c ols: merged edge trigger code from pipistrello-ols (for 3.08 demon core)
ce0aa3761 ols: add a config getter for external clock
These are backend changes only, but because of sigrok's nice design the features are automatically exposed in the applications:
IMG_1123.JPG
The clock edge, external clocking and filter controls weren't there before.

Using synchronous capture increases the number of instructions from 680 to 3,400 (a factor of ~5x). Which is great, but as you can imagine, it's quite hard to work with this number of instructions in the PulseView GUI, so I've also been trying out the command line tool sigrok-cli.

Here's a sigrok-cli command that just tells you the capabilities of your logic analyzer:

Code: Select all

sigrok-cli -d ols:conn=/dev/ttyUSB1:serialcomm=921600/8n1 --channels 0,15 --show
For my Logic Sniffer I see:

Code: Select all

Driver functions:
    Logic analyzer
Scan options:
    conn
    serialcomm
ols - Open Logic Sniffer v1.01 FPGA version 3.08 with 32 channels: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Supported configuration options:
    Maximum number of samples: 12288
    samplerate (10 Hz - 200 MHz in steps of 1 Hz)
    Supported triggers: 0 1 r f 
    captureratio: 0 (current)
    pattern: None (current), External, Internal
    external_clock: on, off (current)
    clock_edge: r (current), f
    filter: on, off (current)
    swap: on, off
    rle: on, off (current)
Here's a sigrok-cli command to actually do some data capture and feed it through the 6502 decoder:

Code: Select all

sigrok-cli \
  -d ols:conn=/dev/ttyUSB1:serialcomm=921600/8n1 \
  --config samplerate=2MHz:external_clock=on:clock_edge=f:captureratio=0 \
  --channels 0-11 \
  --triggers 8=r \
  --protocol-decoders mos6502:d0=0:d1=1:d2=2:d3=3:d4=4:d5=5:d6=6:d7=7:rnw=8:sync=9:rdy=10 \
  --protocol-decoder-annotations mos6502=instr \
  --samples=12288
These seems very complicated, but if you work through it line by line it's not that bad.

This specifies which driver to use for the logic analyzer hardware and which serial port parameters to use.

Code: Select all

-d ols:conn=/dev/ttyUSB1:serialcomm=921600/8n1
This configures the logic analyzer to sample using the falling edge of the external clock input (which is also connected to Phi2):

Code: Select all

--config samplerate=2MHz:external_clock=on:clock_edge=f:captureratio=0
This configures the channels to capture:

Code: Select all

--channels 0-11
This configures the rising edge of channel 8 (Rnw) as the trigger.

Code: Select all

--triggers 8=r
This configures the 6502 protocol decoder, so it knows how things are wired up:

Code: Select all

--protocol-decoders mos6502:d0=0:d1=1:d2=2:d3=3:d4=4:d5=5:d6=6:d7=7:rnw=8:sync=9:rdy=10
This configures what we want to see as output, i.e. just the instructions:

Code: Select all

--protocol-decoder-annotations mos6502=instr
This tells the CLI to acquire a number of samples and then exit:

Code: Select all

--samples=12288
You can put this in a small script to you don't have to remember it, then
- hold down break on the Master
- run the script
- release break

Here's the first few hundred lines of the result:

Code: Select all

mos6502-1: ????: STA 0D00
mos6502-1: ????: SEI
mos6502-1: ????: LDA #53
mos6502-1: ????: STA FE8E
mos6502-1: ????: JSR E590
mos6502-1: E590: LDA #0F
mos6502-1: E592: STA F4
mos6502-1: E594: STA FE30
mos6502-1: E597: RTS
mos6502-1: E372: JMP 8020
mos6502-1: 8020: LDA #FE
mos6502-1: 8022: TRB FE34
mos6502-1: 8025: STZ DFDD
mos6502-1: 8028: TRB 0366
mos6502-1: 802B: CLD
mos6502-1: 802C: LDX #FF
mos6502-1: 802E: TXS
mos6502-1: 802F: STX FE63
mos6502-1: 8032: LDA #CF
mos6502-1: 8034: STA FE42
mos6502-1: 8037: LDY #20
mos6502-1: 8039: LDX #0A
mos6502-1: 803B: JSR 98E4
mos6502-1: 98E4: PHP
mos6502-1: 98E5: SEI
mos6502-1: 98E6: JSR 9906
mos6502-1: 9906: LDA #02
mos6502-1: 9908: STA FE40
mos6502-1: 990B: LDA #82
mos6502-1: 990D: STA FE40
mos6502-1: 9910: LDA #FF
mos6502-1: 9912: STA FE43
mos6502-1: 9915: STX FE4F
mos6502-1: 9918: LDA #C2
mos6502-1: 991A: STA FE40
mos6502-1: 991D: LDA #42
mos6502-1: 991F: STA FE40
mos6502-1: 9922: RTS
mos6502-1: 98E9: LDA #41
mos6502-1: 98EB: STA FE40
mos6502-1: 98EE: LDA #FF
mos6502-1: 98F0: STA FE43
mos6502-1: 98F3: LDA #4A
mos6502-1: 98F5: STA FE40
mos6502-1: 98F8: STY FE4F
mos6502-1: 98FB: BRA 98CC
mos6502-1: 98CC: LDA #42
mos6502-1: 98CE: STA FE40
mos6502-1: 98D1: LDA #02
mos6502-1: 98D3: STA FE40
mos6502-1: 98D6: STZ FE43
mos6502-1: 98D9: PLP
mos6502-1: 98DA: TYA
mos6502-1: 98DB: RTS
mos6502-1: 803E: JSR 9729
mos6502-1: 9729: LDX #0B
mos6502-1: 972B: LDY #02
mos6502-1: 972D: JMP 98E4
mos6502-1: 98E4: PHP
mos6502-1: 98E5: SEI
mos6502-1: 98E6: JSR 9906
mos6502-1: 9906: LDA #02
mos6502-1: 9908: STA FE40
mos6502-1: 990B: LDA #82
mos6502-1: 990D: STA FE40
mos6502-1: 9910: LDA #FF
mos6502-1: 9912: STA FE43
mos6502-1: 9915: STX FE4F
mos6502-1: 9918: LDA #C2
mos6502-1: 991A: STA FE40
mos6502-1: 991D: LDA #42
mos6502-1: 991F: STA FE40
mos6502-1: 9922: RTS
mos6502-1: 98E9: LDA #41
mos6502-1: 98EB: STA FE40
mos6502-1: 98EE: LDA #FF
mos6502-1: 98F0: STA FE43
mos6502-1: 98F3: LDA #4A
mos6502-1: 98F5: STA FE40
mos6502-1: 98F8: STY FE4F
mos6502-1: 98FB: BRA 98CC
mos6502-1: 98CC: LDA #42
mos6502-1: 98CE: STA FE40
mos6502-1: 98D1: LDA #02
mos6502-1: 98D3: STA FE40
mos6502-1: 98D6: STZ FE43
mos6502-1: 98D9: PLP
mos6502-1: 98DA: TYA
mos6502-1: 98DB: RTS
mos6502-1: 8041: LDA #0C
mos6502-1: 8043: TSB FE34
mos6502-1: 8046: LDA FE4E
mos6502-1: 8049: ASL A
mos6502-1: 804A: PHA
mos6502-1: 804B: BEQ 8054
mos6502-1: 804D: LDA 0258
mos6502-1: 8050: LSR A
mos6502-1: 8051: DEC A
mos6502-1: 8052: BNE 8073
mos6502-1: 8073: LDA #11
mos6502-1: 8075: STA DF04
mos6502-1: 8078: LDA #E8
mos6502-1: 807A: STA DF05
mos6502-1: 807D: LDA #0C
mos6502-1: 807F: TRB FE34
mos6502-1: 8082: LDA #0F
mos6502-1: 8084: STA 028E
mos6502-1: 8087: DEC A
mos6502-1: 8088: STA FE40
mos6502-1: 808B: CMP #09
mos6502-1: 808D: BCS 8087
mos6502-1: 8087: DEC A
mos6502-1: 8088: STA FE40
mos6502-1: 808B: CMP #09
mos6502-1: 808D: BCS 8087
mos6502-1: 8087: DEC A
mos6502-1: 8088: STA FE40
mos6502-1: 808B: CMP #09
mos6502-1: 808D: BCS 8087
mos6502-1: 8087: DEC A
mos6502-1: 8088: STA FE40
mos6502-1: 808B: CMP #09
mos6502-1: 808D: BCS 8087
mos6502-1: 8087: DEC A
mos6502-1: 8088: STA FE40
mos6502-1: 808B: CMP #09
mos6502-1: 808D: BCS 8087
mos6502-1: 8087: DEC A
mos6502-1: 8088: STA FE40
mos6502-1: 808B: CMP #09
mos6502-1: 808D: BCS 8087
mos6502-1: 8087: DEC A
mos6502-1: 8088: STA FE40
mos6502-1: 808B: CMP #09
mos6502-1: 808D: BCS 8087
mos6502-1: 808F: LDX #01
mos6502-1: 8091: JSR F880
mos6502-1: F880: LDY #03
mos6502-1: F882: STY FE40
mos6502-1: F885: LDY #7F
mos6502-1: F887: STY FE43
mos6502-1: F88A: STX FE4F
mos6502-1: F88D: NOP
mos6502-1: F88E: LDX FE4F
mos6502-1: F891: RTS
mos6502-1: 8094: CPX #80
mos6502-1: 8096: JSR F735
mos6502-1: F735: PHP
mos6502-1: F736: LDA 025A
mos6502-1: F739: LSR A
mos6502-1: F73A: AND #18
mos6502-1: F73C: ORA #06
mos6502-1: F73E: STA FE40
mos6502-1: F741: LSR A
mos6502-1: F742: ORA #07
mos6502-1: F744: STA FE40
mos6502-1: F747: JSR F91C
mos6502-1: F91C: LDA #0B
mos6502-1: F91E: STA FE40
mos6502-1: F921: TXA
mos6502-1: F922: RTS
mos6502-1: F74A: PLA
mos6502-1: F74B: RTS
mos6502-1: 8099: STZ 028D
mos6502-1: 809C: ROR A
mos6502-1: 809D: LDX #9C
mos6502-1: 809F: LDY #8D
mos6502-1: 80A1: PLA
mos6502-1: 80A2: BEQ 80AD
mos6502-1: 80A4: LDY #7E
mos6502-1: 80A6: BCC 80DF
mos6502-1: 80DF: LDA #87
mos6502-1: 80E1: TRB 028F
mos6502-1: 80E4: LDA 0355
mos6502-1: 80E7: AND #07
mos6502-1: 80E9: TSB 028F
mos6502-1: 80EC: LDA #10
mos6502-1: 80EE: BIT D0
mos6502-1: 80F0: BEQ 80F7
mos6502-1: 80F7: LDA 028D
mos6502-1: 80FA: BNE 8104
mos6502-1: 80FC: CPX #B1
mos6502-1: 80FE: BCS 8104
mos6502-1: 8100: CPX #A1
mos6502-1: 8102: BCS 810E
mos6502-1: 8104: STZ 0200,X
mos6502-1: 8107: CPX #CD
mos6502-1: 8109: BCC 810E
mos6502-1: 810E: INX
mos6502-1: 810F: BNE 80F7
mos6502-1: 80F7: LDA 028D
mos6502-1: 80FA: BNE 8104
mos6502-1: 80FC: CPX #B1
mos6502-1: 80FE: BCS 8104
mos6502-1: 8100: CPX #A1
mos6502-1: 8102: BCS 810E
mos6502-1: 8104: STZ 0200,X
mos6502-1: 8107: CPX #CD
mos6502-1: 8109: BCC 810E
mos6502-1: 810E: INX
You can see the algorithm for predicting the PC value kicks in at the first change of control flow (a JSR in this case).

Imagine you had a Master that wasn't working. All you would have to do would be do a similar capture and see where it is different from a "known good" reference. That give you be a big clue as to what's broken.

to be continued....
Last edited by hoglet on Sat Oct 14, 2017 2:54 pm, edited 4 times in total.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sat Oct 14, 2017 12:08 pm

Part 5: Using an uber-cheap FX2LP development board

The postman has just delivered a £12.49 Cypress FX2LP development board which can be used as a 16-channel logic analyzer.

I bought this from Hobby Components:
http://hobbycomponents.com/cypress/674- ... c-analyser

Here's their picture of it:
hobby-components-cy7c68013a-16ch-logic-analyser.jpg
This is a bit different to the logic sniffer as it contains almost no on-board memory. Instead, it streams data to the host, which allows (in principle) for very long captures. But the capture rate is more limited: at 16 channels it allows a maximum of 12MHz sampling. But that should be enough :D

Here it is wired up to the Master 128:
IMG_1124.JPG
The 40-pin DIP test clip is by far the most expensive part of the setup, and these can sometimes be found on eBay for about £20.

Here's some information about using it in sigrok:
https://sigrok.org/wiki/Lcsoft_Mini_Board

So does it work???

Yes indeed... Here's a capture of 1 million samples (about 83 ms of activity):
sigrok10.png
And zooming in on one of the interrupts, it's correctly decoded the instruction stream.
sigrok11.png
It does seem the 6502 protocol decoder is the bottleneck here, as it takes a few seconds to build that view. The hardware also seems a little flaky - it crashes when you exit pulseview and needs to be reset (there is a button for this). But I'm sure that will be sortable.

There is no triggering capability in the hardware, but it seems sigrok can do simple triggering in software.

Here's it triggering on the rising edge of RSTn:
sigrok12.png
It's interesting that IRQn goes low for a long time. Zooming in, you can see what's happening:
sigrok13.png
It looks like this in the VDU driver clearing the screen. My master uses MODE 0. Clearing 20K at 8 cycles per byte will take about 80ms.

It also works reasonably well with the sigrok-cli client:

Code: Select all

$ sigrok-cli -d fx2lafw --config samplerate=12MHz  \
   --channels D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14 \
   --protocol-decoders mos6502:d0=D0:d1=D1:d2=D2:d3=D3:d4=D4:d5=D5:d6=D6:d7=D7:rnw=D8:sync=D9:rdy=D10:phi2=D11
   --triggers D14=r \
   --protocol-decoder-annotations mos6502=instr --samples=10M > instructions
Device only sent 1886772 samples.

$ wc -l instructions 
86372 instructions

$ head instructions 
mos6502-1: E364: LDA #40
mos6502-1: E366: STA 0D00
mos6502-1: E369: SEI
mos6502-1: E36A: LDA #53
mos6502-1: E36C: STA FE8E
mos6502-1: E36F: JSR E590
mos6502-1: E590: LDA #0F
mos6502-1: E592: STA F4
mos6502-1: E594: STA FE30
mos6502-1: E597: RTS

$ tail instructions 
mos6502-1: E7DC: BCS E7F3
mos6502-1: E7DE: LDX 0241
mos6502-1: E7E1: JSR EAFD
mos6502-1: EAFD: BIT 025F
mos6502-1: EB00: BPL EB07
mos6502-1: EB07: LDA 0268
mos6502-1: EB0A: BEQ EAC3
mos6502-1: EAC3: JSR E9F4
mos6502-1: E9F4: CLV
mos6502-1: E9F5: JMP (022C)
I'm not sure what's limiting it to about 1.8M samples.

However, a work around seems to be to capture the data to a binary file, then run the protocol decoder afterwards:

Code: Select all

$ sigrok-cli -d fx2lafw --config samplerate=12MHz \
  --channels D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14 \
  -o data.bin -O binary --triggers D14=r --samples=10M

$  sigrok-cli -i data.bin -I binary:numchannels=15:samplerate=12MHz \
  --protocol-decoders mos6502:d0=0:d1=1:d2=2:d3=3:d4=4:d5=5:d6=6:d7=7:rnw=8:sync=9:rdy=10:phi2=11 
  --protocol-decoder-annotations mos6502=instr > instructions

$ wc -l instructions 
461063 instructions

$ head instructions 
mos6502-1: E364: LDA #40
mos6502-1: E366: STA 0D00
mos6502-1: E369: SEI
mos6502-1: E36A: LDA #53
mos6502-1: E36C: STA FE8E
mos6502-1: E36F: JSR E590
mos6502-1: E590: LDA #0F
mos6502-1: E592: STA F4
mos6502-1: E594: STA FE30
mos6502-1: E597: RTS

$ tail instructions 
mos6502-1: E7E6: BIT E6
mos6502-1: E7E8: BPL E7D7
mos6502-1: E7D7: LDA FF
mos6502-1: E7D9: ASL A
mos6502-1: E7DA: LDA #1B
mos6502-1: E7DC: BCS E7F3
mos6502-1: E7DE: LDX 0241
mos6502-1: E7E1: JSR EAFD
mos6502-1: EAFD: BIT 025F
mos6502-1: EB00: BPL EB07
It seems with this method the capture size is unlimited (I successfully captured 100 million samples :shock: ); the limiting factor is how long the offline protocol decoder takes to run. It might be worth writing a more specialized implementation in C.

sigrok-cli also outputs .vcd files, so that opens up the possibility of using excellent tools like gtkwave. I haven't explored this yet.

Dave
Last edited by hoglet on Sat Oct 14, 2017 5:38 pm, edited 3 times in total.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sat Oct 14, 2017 2:15 pm

Part 6: Simplifying capture on the Beeb Model B

It's been pointed out that one of the barriers to more widespread use of this logic analyzers for debugging is the practicality of connecting to the various signals on the 6502. I'm using a professional Pomona 40-pin DIP test clip, but these are quite pricey (£20-£40):
IMG_1138.JPG
On the Model B, almost all the necessary 6502 signals appear on the Tube connector, so wouldn't it be nice if you could just connect your £15 USB Logic Analyzer directly to that?

Specifically, the Tube Connector has the following signals (plus a few more we don't use):
- 2MHzE
- D0..7
- RnW
- RST

Unfortunately, there is one crucial missing signal, sync, which is used by the 6502 to mark the beginning of the each instruction (i.e. the cycle where the opcode is being fetched). The first version of the 6502 bus protocol decoder made very extensive use of sync to determine the boundaries between instructions.

It turns out that with a little ingenuity its possible to get some very decent results without using sync. But the decoder needs to be much more aware how the 6502 works, including:
- the minimum number of bus cycles for each instruction
- taken branches take an extra cycle (i.e. 3 cycles rather than 2 cycles)
- certain addressing modes take an extra cycle when a page is crossed

By knowing exactly how many cycles an instruction takes, it should be possible to lock on, and stay locked on, to an instruction stream. There's a good analogy here to a disassembler. Even if you start disassembling at a random address, pretty soon you will hit the correct instruction alignment and then you stay aligned.

Where it gets complicated is that to be able to predict whether branches are taken means the decoder has to model each of the 6502 flags. Similarly, to predict whether "LDA absolute, X" takes 4 or 5 cycles, it has to know the value of the X register. So it starts to become more like a full 6502 emulator, but one that has to deal with uncertainty, because initially none of the register or flag values are known.

So, with this goal in mind, over the last couple of weeks I've been rewriting the decoder. It now has it's own github repository (here), and it's been re-written now as a standalone C program. Which means it runs about 200x faster than the original python program.

Here's a photo of the cheap USB logic analyzer hooked up to the Tube connector:
IMG_1136.JPG
The connections are:

Code: Select all

Tube Connector -> Logic Analyzer
-------------     --------------
Pin  1    (0V) -> GND
Pin  2   (RnW) -> PD0
Pin  4 (2MHzE) -> PD3
Pin 10  (NRST) -> PD6
Pin 11    (0V) -> GND
Pin 12    (D0) -> PB0
Pin 14    (D1) -> PB1
Pin 16    (D2) -> PB2
Pin 18    (D3) -> PB3
Pin 20    (D4) -> PB4
Pin 22    (D5) -> PB5
Pin 24    (D6) -> PB6
Pin 26    (D7) -> PB7
I'm still using sigrok-cli to capture the data (to a binary file):

Code: Select all

$ sigrok-cli -d fx2lafw --config samplerate=12MHz:captureratio=1  -o data1.bin -O binary --triggers D14=r --samples=12M
The trigger for here is the rising edge of reset, and we have captured 1 second of data (12 million samples).

You then then process the binary capture file with the new 6502 protocol decoder:

Code: Select all

$ decode6502 -h -s --sync= <data.bin >data.txt
The --sync= param tells it the sync signal is not connected, and causes it to switch to the syncless decoding algorithm.

And here's the result:

Code: Select all

???? :          : RESET !!      A=?? X=?? Y=?? SP=?? N=? V=? D=? I=1 Z=? C=?
D9CD : A9 40    : LDA #40       A=40 X=?? Y=?? SP=?? N=0 V=? D=? I=1 Z=0 C=?
D9CF : 8D 00 0D : STA 0D00      A=40 X=?? Y=?? SP=?? N=0 V=? D=? I=1 Z=0 C=?
D9D2 : 78       : SEI           A=40 X=?? Y=?? SP=?? N=0 V=? D=? I=1 Z=0 C=?
D9D3 : D8       : CLD           A=40 X=?? Y=?? SP=?? N=0 V=? D=0 I=1 Z=0 C=?
D9D4 : A2 FF    : LDX #FF       A=40 X=FF Y=?? SP=?? N=1 V=? D=0 I=1 Z=0 C=?
D9D6 : 9A       : TXS           A=40 X=FF Y=?? SP=FF N=1 V=? D=0 I=1 Z=0 C=?
D9D7 : AD 4E FE : LDA FE4E      A=80 X=FF Y=?? SP=FF N=1 V=? D=0 I=1 Z=0 C=?
D9DA : 0A       : ASL A         A=00 X=FF Y=?? SP=FF N=0 V=? D=0 I=1 Z=1 C=1
D9DB : 48       : PHA           A=00 X=FF Y=?? SP=FE N=0 V=? D=0 I=1 Z=1 C=1
D9DC : F0 09    : BEQ D9E7      A=00 X=FF Y=?? SP=FE N=0 V=? D=0 I=1 Z=1 C=1
D9E7 : A2 04    : LDX #04       A=00 X=04 Y=?? SP=FE N=0 V=? D=0 I=1 Z=0 C=1
D9E9 : 86 01    : STX 01        A=00 X=04 Y=?? SP=FE N=0 V=? D=0 I=1 Z=0 C=1
D9EB : 85 00    : STA 00        A=00 X=04 Y=?? SP=FE N=0 V=? D=0 I=1 Z=0 C=1
D9ED : A8       : TAY           A=00 X=04 Y=00 SP=FE N=0 V=? D=0 I=1 Z=1 C=1
D9EE : 91 00    : STA (00),Y    A=00 X=04 Y=00 SP=FE N=0 V=? D=0 I=1 Z=1 C=1
D9F0 : C5 01    : CMP 01        A=00 X=04 Y=00 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F2 : F0 09    : BEQ D9FD      A=00 X=04 Y=00 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F4 : C8       : INY           A=00 X=04 Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9F5 : D0 F7    : BNE D9EE      A=00 X=04 Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
....
D9EE : 91 00    : STA (00),Y    A=00 X=7F Y=FF SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F0 : C5 01    : CMP 01        A=00 X=7F Y=FF SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F2 : F0 09    : BEQ D9FD      A=00 X=7F Y=FF SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F4 : C8       : INY           A=00 X=7F Y=00 SP=FE N=0 V=? D=0 I=1 Z=1 C=0
D9F5 : D0 F7    : BNE D9EE      A=00 X=7F Y=00 SP=FE N=0 V=? D=0 I=1 Z=1 C=0
D9F7 : C8       : INY           A=00 X=7F Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9F8 : E8       : INX           A=00 X=80 Y=01 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F9 : E6 01    : INC 01        A=00 X=80 Y=01 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9FB : 10 F1    : BPL D9EE      A=00 X=80 Y=01 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9FD : 8E 8E 02 : STX 028E      A=00 X=80 Y=01 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
DA00 : 8E 84 02 : STX 0284      A=00 X=80 Y=01 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
DA03 : A2 0F    : LDX #0F       A=00 X=0F Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
DA05 : 8E 42 FE : STX FE42      A=00 X=0F Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
DA08 : CA       : DEX           A=00 X=0E Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
DA09 : 8E 40 FE : STX FE40      A=00 X=0E Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
DA0C : E0 09    : CPX #09       A=00 X=0E Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0E : B0 F8    : BCS DA08      A=00 X=0E Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA08 : CA       : DEX           A=00 X=0D Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA09 : 8E 40 FE : STX FE40      A=00 X=0D Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0C : E0 09    : CPX #09       A=00 X=0D Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0E : B0 F8    : BCS DA08      A=00 X=0D Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA08 : CA       : DEX           A=00 X=0C Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA09 : 8E 40 FE : STX FE40      A=00 X=0C Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0C : E0 09    : CPX #09       A=00 X=0C Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0E : B0 F8    : BCS DA08      A=00 X=0C Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA08 : CA       : DEX           A=00 X=0B Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA09 : 8E 40 FE : STX FE40      A=00 X=0B Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0C : E0 09    : CPX #09       A=00 X=0B Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0E : B0 F8    : BCS DA08      A=00 X=0B Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA08 : CA       : DEX           A=00 X=0A Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA09 : 8E 40 FE : STX FE40      A=00 X=0A Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0C : E0 09    : CPX #09       A=00 X=0A Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0E : B0 F8    : BCS DA08      A=00 X=0A Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA08 : CA       : DEX           A=00 X=09 Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA09 : 8E 40 FE : STX FE40      A=00 X=09 Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=1
DA0C : E0 09    : CPX #09       A=00 X=09 Y=01 SP=FE N=0 V=? D=0 I=1 Z=1 C=1
DA0E : B0 F8    : BCS DA08      A=00 X=09 Y=01 SP=FE N=0 V=? D=0 I=1 Z=1 C=1
You can see initially the register state is unknown, but as successive instructions are executed it becomes known.

The above example started with a RESET, so here's a harder case, starting in the middle of a running BBC Basic program:

Code: Select all

???? : 01 8A    : ORA (8A,X)    A=?? X=?? Y=?? SP=?? N=? V=? D=? I=? Z=? C=?
???? : 98       : TYA           A=?? X=?? Y=?? SP=?? N=? V=? D=? I=? Z=? C=?
???? : 48       : PHA           A=00 X=?? Y=?? SP=?? N=? V=? D=? I=? Z=? C=?
???? : BA       : TSX           A=00 X=?? Y=?? SP=?? N=? V=? D=? I=? Z=? C=?
???? : BD 03 01 : LDA 0103,X    A=01 X=?? Y=?? SP=?? N=0 V=? D=? I=? Z=0 C=?
???? : 48       : PHA           A=01 X=?? Y=?? SP=?? N=0 V=? D=? I=? Z=0 C=?
???? : 2C 60 02 : BIT 0260      A=01 X=?? Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=?
???? : 10 08    : BPL pc-8      A=01 X=?? Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=?
???? : 18       : CLC           A=01 X=?? Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
???? : A9 02    : LDA #02       A=02 X=?? Y=?? SP=?? N=0 V=0 D=? I=? Z=0 C=0
???? : 2C 7C 02 : BIT 027C      A=02 X=?? Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
???? : D0 05    : BNE pc-5      A=02 X=?? Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
???? : 68       : PLA           A=01 X=?? Y=?? SP=?? N=0 V=0 D=? I=? Z=0 C=0
???? : 48       : PHA           A=01 X=?? Y=?? SP=?? N=0 V=0 D=? I=? Z=0 C=0
???? : 20 C0 C4 : JSR C4C0      A=01 X=?? Y=?? SP=?? N=0 V=0 D=? I=? Z=0 C=0
C4C0 : AE 6A 02 : LDX 026A      A=01 X=FD Y=?? SP=?? N=1 V=0 D=? I=? Z=0 C=0
C4C3 : D0 4D    : BNE C512      A=01 X=FD Y=?? SP=?? N=1 V=0 D=? I=? Z=0 C=0
C512 : 9D 24 02 : STA 0224,X    A=01 X=FD Y=?? SP=?? N=1 V=0 D=? I=? Z=0 C=0
C515 : E8       : INX           A=01 X=FE Y=?? SP=?? N=1 V=0 D=? I=? Z=0 C=0
C516 : 8E 6A 02 : STX 026A      A=01 X=FE Y=?? SP=?? N=1 V=0 D=? I=? Z=0 C=0
C519 : D0 17    : BNE C532      A=01 X=FE Y=?? SP=?? N=1 V=0 D=? I=? Z=0 C=0
C532 : 18       : CLC           A=01 X=FE Y=?? SP=?? N=1 V=0 D=? I=? Z=0 C=0
C533 : 60       : RTS           A=01 X=FE Y=?? SP=?? N=1 V=0 D=? I=? Z=0 C=0
E0C8 : A9 08    : LDA #08       A=08 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=0 C=0
E0CA : 2C 7C 02 : BIT 027C      A=08 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0CD : D0 02    : BNE E0D1      A=08 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0CF : 90 05    : BCC E0D6      A=08 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0D6 : AD 7C 02 : LDA 027C      A=00 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0D9 : 6A       : ROR A         A=00 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0DA : 90 1B    : BCC E0F7      A=00 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0F7 : A9 10    : LDA #10       A=10 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=0 C=0
E0F9 : 2C 7C 02 : BIT 027C      A=10 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0FC : D0 0F    : BNE E10D      A=10 X=FE Y=?? SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0FE : AC 57 02 : LDY 0257      A=10 X=FE Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E101 : F0 0A    : BEQ E10D      A=10 X=FE Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E10D : 68       : PLA           A=01 X=FE Y=00 SP=?? N=0 V=0 D=? I=? Z=0 C=0
E10E : 68       : PLA           A=00 X=FE Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E10F : A8       : TAY           A=00 X=FE Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E110 : 68       : PLA           A=37 X=FE Y=00 SP=?? N=0 V=0 D=? I=? Z=0 C=0
E111 : AA       : TAX           A=37 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=0 C=0
E112 : 68       : PLA           A=01 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=0 C=0
E113 : 60       : RTS           A=01 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=0 C=0
941F : 20 56 94 : JSR 9456      A=01 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=0 C=0
9456 : A5 2A    : LDA 2A        A=C7 X=37 Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
9458 : 6C 0E 02 : JMP (020E)    A=C7 X=37 Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
E0A4 : 48       : PHA           A=C7 X=37 Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
E0A5 : 8A       : TXA           A=37 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=0 C=0
E0A6 : 48       : PHA           A=37 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=0 C=0
E0A7 : 98       : TYA           A=00 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0A8 : 48       : PHA           A=00 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0A9 : BA       : TSX           A=00 X=37 Y=00 SP=?? N=? V=0 D=? I=? Z=? C=0
E0AA : BD 03 01 : LDA 0103,X    A=C7 X=37 Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
E0AD : 48       : PHA           A=C7 X=37 Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
E0AE : 2C 60 02 : BIT 0260      A=C7 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0B1 : 10 08    : BPL E0BB      A=C7 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0BB : 18       : CLC           A=C7 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0BC : A9 02    : LDA #02       A=02 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=0 C=0
E0BE : 2C 7C 02 : BIT 027C      A=02 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0C1 : D0 05    : BNE E0C8      A=02 X=37 Y=00 SP=?? N=0 V=0 D=? I=? Z=1 C=0
E0C3 : 68       : PLA           A=C7 X=37 Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
E0C4 : 48       : PHA           A=C7 X=37 Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
E0C5 : 20 C0 C4 : JSR C4C0      A=C7 X=37 Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
C4C0 : AE 6A 02 : LDX 026A      A=C7 X=FE Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
C4C3 : D0 4D    : BNE C512      A=C7 X=FE Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
C512 : 9D 24 02 : STA 0224,X    A=C7 X=FE Y=00 SP=?? N=1 V=0 D=? I=? Z=0 C=0
It takes a bit longer to "lock on", and SP and D remain unknown. This was the SPHERE benchmark by the way.

Here's the full help for the decode6502 command:

Code: Select all

$ decode6502 --help
Usage: decode6502 [OPTION...] [FILENAME]

Decoder for 6502/65C02 logic analyzer capture files.

FILENAME must be a binary capture file with 16 bit samples.

If FILENAME is omitted, stdin is read instead.

The default bit assignments for the input signals are:
 - data: bit  0 (assumes 8 consecutive bits)
 -  rnw: bit  8
 - sync: bit  9
 -  rdy: bit 10
 - phi2: bit 11
 -  rst: bit 14

To specify that an input is unconnected, include the option with an empty
BITNUM. e.g. --sync=

If phi2 is not connected the capture file should contain one sample per
falling edge of phi2.

If rdy is not connected a value of '1' is assumed.

If sync is not connected a heuristic based decoder is used. This works well,
but can take several instructions to lock onto the instruction stream.
Use of sync, is preferred.

  -c, --c02                  Enable 65C02 mode.
      --data=BITNUM          The start bit number for data
  -d, --debug=LEVEL          Sets debug level (0 1 or 2)
  -h, --hex                  Show hex bytes of instruction.
      --phi2[=BITNUM]        The bit number for phi2, blank if unconnected
      --rdy[=BITNUM]         The bit number for rdy, blank if unconnected
      --rnw=BITNUM           The bit number for rnw
      --rst[=BITNUM]         The bit number for rst, blank if unconnected
      --sync[=BITNUM]        The bit number for sync, blank if unconnected
  -s, --state                Show register/flag state.
  -u, --undocumented         Enable undocumented 6502 opcodes (currently
                             incomplete)
  -?, --help                 Give this help list
      --usage                Give a short usage message
  -V, --version              Print program version

Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.

Report bugs to <dave@hoglet.com>.
I'm using decode6502 on Linux (Ubuntu 16.04), but it should be possible to build it using the bash shell on Window 10.

If anyone wants to take this for a spin, please do ask for help if needed. It would be great to have someone try this on a Beeb that was failing to start for example. It should then be possible to narrow down the fault very quickly indeed.

Dave

P.S. This isn't quite as straight forward on the Master. The external tube is buffered, so the internal tube would have to be used. And also the master uses Rdy rather than cycle stretching, so one additional wire is still required, at least currently.
Last edited by hoglet on Mon Nov 20, 2017 12:15 pm, edited 5 times in total.

dp11
Posts: 841
Joined: Sun Aug 12, 2012 8:47 pm
Contact:

Re: Open Source Logic Analyzer Experiments

Post by dp11 » Sat Oct 14, 2017 3:36 pm

this is amazing work. The pc calculation is very clever. You could also work backwards ofne you know the first true address to fill in the blanks as the JSR stacks where you currently are, the same for IRQ. actually I think a double or triple write will contain the address of where you currently are in a 65c02

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sat Oct 14, 2017 4:10 pm

Part 7: Using Sigrok-cli / FX2 Logic Analyzer / 6502 Decoder on Windows

Parts 1 - 6 were written from the perspective of a Linux user. In Part 7, we show how to get up and running on Windows.

Step 1: Install Sigrok-cli and FX2 Logic Analyzer Drivers

- Follow the instructions from Hobby Components here except use the sigrok installer links here (the links on the Hobby Components page are broken).

- Add the following to your Windows PATH environment variable:

Code: Select all

C:\Program Files (x86)\sigrok\sigrok-cli
To do this, in the windows search box type "env" and the select "Edit environment variables for your account" and then edit the Path variable and add C:\Program Files (x86)sigrok\sigrok-cli; to the front of it.

Step 2: Test Sigrok-cli installation

- Disconnect the FX Logic Analyzer from the PC

- Reconnect the FX Logic Analyzer to the PC (make sure it's a USB-2 port)

- Start a fresh Windows Cmd shell, and run:

Code: Select all

sigrok-cli -d fx2lafw --show
You should see the following:
cmd1.png
Step 3a Build the 6502 Decoder (Windows 7)

The best way to build the 6502 Decoder in Windows 7 is to use CygWin.

- Download CygWin (64 bit) setup tool from here:
https://cygwin.com/install.html

- Run the setup tool and accept all the defaults

- Re-run the setup tool and install the following additional packages:
-- git
-- gcc-core
-- libargp-devel
inst1.png
- Start a Cygwin64 Terminal

- Run the following commands:

Code: Select all

git clone https://github.com/hoglet67/6502Decoder.git
cd 6502Decoder/
gcc -Wall -O3 -o decode6502 src/main.c src/em_6502.c -l argp
gunzip < test/beeb/reset.bin.gz | ./decode6502.exe -s -h --phi2= | head
inst2.png
Step 3b: Build the 6502 Decoder (Windows 10)

In Windows 10, instead of using CygWin it's simpler to use the built-in bash command shell.

- Open a WIndows 10 Bash Command Prompt

- Run the following commands:

Code: Select all

git clone https://github.com/hoglet67/6502Decoder.git
cd 6502Decoder
gcc -Wall -O3 -o decode6502.exe src/main.c src/em_6502.c
- You should now have built decode6502.exe in the current directory

Step 4: Hook up the FX2 Logic Analyzer to the Beeb's Tube port

The connections are:

Code: Select all

Tube Connector -> Logic Analyzer
-------------     --------------
Pin  1    (0V) -> GND
Pin  2   (RnW) -> PD0
Pin  4 (2MHzE) -> PD3
Pin  6  (NIRQ) -> PD4
Pin  8 (NTUBE) -> PD7 (not actually used yet)
Pin 10  (NRST) -> PD6 (not actually used yet)
Pin 12    (D0) -> PB0
Pin 14    (D1) -> PB1
Pin 16    (D2) -> PB2
Pin 18    (D3) -> PB3
Pin 20    (D4) -> PB4
Pin 22    (D5) -> PB5
Pin 24    (D6) -> PB6
Pin 26    (D7) -> PB7
The easier way to do this is to use a short lenth of IDC cable with two 40-pin female connectors, and then 14 male-female flying leads.
IMG_1246.JPG
(Or get one of Myelin's adapter board)

Step 5: Run your first capture of the Beeb booting

- Initially the Beeb should be powered off.

- Start a Cygwin64 Terminal, and run:

Code: Select all

cd Decode6502
sigrok-cli -d fx2lafw --config samplerate=12MHz:captureratio=1  -o data.bin -O binary --triggers D14=r --samples=12M
- Wait a few seconds (the command should not exit) then power on the Beeb. After one second, the sigrok-cli command should complete and you should have a file called data.bin that is exactly 24,000,000 bytes long. If the file is shorter than this, or if you get a "Device only sent xxx samples" error, then there is a performance issue with your system. Check you have plugged the device into a USB-2 capable port.

- Run the 6502 decoder:

Code: Select all

./decode6502 -h -s --sync= data.bin > data.txt
- Check the number of instructions captured (should be ~567,000):

Code: Select all

wc -l data.txt
- Check the number of decoder failures (should be 0):

Code: Select all

grep fail data.txt | wc -l
- View the results file:

Code: Select all

more data.txt
The resulting data.txt file should start off with:

Code: Select all

???? :          : RESET !!       : A=?? X=?? Y=?? SP=?? N=? V=? D=? I=1 Z=? C=?
D9CD : A9 40    : LDA #40        : A=40 X=?? Y=?? SP=?? N=0 V=? D=? I=1 Z=0 C=?
D9CF : 8D 00 0D : STA 0D00       : A=40 X=?? Y=?? SP=?? N=0 V=? D=? I=1 Z=0 C=?
D9D2 : 78       : SEI            : A=40 X=?? Y=?? SP=?? N=0 V=? D=? I=1 Z=0 C=?
D9D3 : D8       : CLD            : A=40 X=?? Y=?? SP=?? N=0 V=? D=0 I=1 Z=0 C=?
D9D4 : A2 FF    : LDX #FF        : A=40 X=FF Y=?? SP=?? N=1 V=? D=0 I=1 Z=0 C=?
D9D6 : 9A       : TXS            : A=40 X=FF Y=?? SP=FF N=1 V=? D=0 I=1 Z=0 C=?
D9D7 : AD 4E FE : LDA FE4E       : A=80 X=FF Y=?? SP=FF N=1 V=? D=0 I=1 Z=0 C=?
D9DA : 0A       : ASL A          : A=00 X=FF Y=?? SP=FF N=0 V=? D=0 I=1 Z=1 C=1
D9DB : 48       : PHA            : A=00 X=FF Y=?? SP=FE N=0 V=? D=0 I=1 Z=1 C=1
D9DC : F0 09    : BEQ D9E7       : A=00 X=FF Y=?? SP=FE N=0 V=? D=0 I=1 Z=1 C=1
D9E7 : A2 04    : LDX #04        : A=00 X=04 Y=?? SP=FE N=0 V=? D=0 I=1 Z=0 C=1
D9E9 : 86 01    : STX 01         : A=00 X=04 Y=?? SP=FE N=0 V=? D=0 I=1 Z=0 C=1
D9EB : 85 00    : STA 00         : A=00 X=04 Y=?? SP=FE N=0 V=? D=0 I=1 Z=0 C=1
D9ED : A8       : TAY            : A=00 X=04 Y=00 SP=FE N=0 V=? D=0 I=1 Z=1 C=1
D9EE : 91 00    : STA (00),Y     : A=00 X=04 Y=00 SP=FE N=0 V=? D=0 I=1 Z=1 C=1
D9F0 : C5 01    : CMP 01         : A=00 X=04 Y=00 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F2 : F0 09    : BEQ D9FD       : A=00 X=04 Y=00 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F4 : C8       : INY            : A=00 X=04 Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9F5 : D0 F7    : BNE D9EE       : A=00 X=04 Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9EE : 91 00    : STA (00),Y     : A=00 X=04 Y=01 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9F0 : C5 01    : CMP 01         : A=00 X=04 Y=01 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F2 : F0 09    : BEQ D9FD       : A=00 X=04 Y=01 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F4 : C8       : INY            : A=00 X=04 Y=02 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9F5 : D0 F7    : BNE D9EE       : A=00 X=04 Y=02 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9EE : 91 00    : STA (00),Y     : A=00 X=04 Y=02 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9F0 : C5 01    : CMP 01         : A=00 X=04 Y=02 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F2 : F0 09    : BEQ D9FD       : A=00 X=04 Y=02 SP=FE N=1 V=? D=0 I=1 Z=0 C=0
D9F4 : C8       : INY            : A=00 X=04 Y=03 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9F5 : D0 F7    : BNE D9EE       : A=00 X=04 Y=03 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
D9EE : 91 00    : STA (00),Y     : A=00 X=04 Y=03 SP=FE N=0 V=? D=0 I=1 Z=0 C=0
If you have any problems, zip up the data.bin file and post it in this thread and I'll take a look.

Dave
Last edited by hoglet on Wed Feb 07, 2018 11:56 pm, edited 21 times in total.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sat Oct 14, 2017 5:36 pm

Part 5 now updated... Time for Strictly :shock:

User avatar
BigEd
Posts: 2140
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Open Source Logic Analyzer Experiments

Post by BigEd » Sat Oct 14, 2017 9:36 pm

hoglet wrote:
dp11 wrote:this is amazing work. The pc calculation is very clever. You could also work backwards [once] you know the first true address to fill in the blanks as the JSR stacks where you currently are, the same for IRQ. actually I think a double or triple write will contain the address of where you currently are in a 65c02
... a good idea (but possibly hard to implement)
Did you figure out Dave if the protocol decoder is allowed to post updates to events which happened some time ago? Back annotation capability, if it happens to be there, would be handy for retrospectively annotating some distance back from the first known address.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sat Oct 14, 2017 9:43 pm

BigEd wrote:
hoglet wrote:
dp11 wrote:this is amazing work. The pc calculation is very clever. You could also work backwards [once] you know the first true address to fill in the blanks as the JSR stacks where you currently are, the same for IRQ. actually I think a double or triple write will contain the address of where you currently are in a 65c02
... a good idea (but possibly hard to implement)
Did you figure out Dave if the protocol decoder is allowed to post updates to events which happened some time ago? Back annotation capability, if it happens to be there, would be handy for retrospectively annotating some distance back from the first known address.
I didn't try to figure that out.

I'm not to inclined to try to implement this back annotation, because it feels much hardware/more complex than what we have done already, but I'm happy if you or Dominic want to have a go!

Dave

User avatar
BigEd
Posts: 2140
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Open Source Logic Analyzer Experiments

Post by BigEd » Sat Oct 14, 2017 9:47 pm

Ha ha - I walked into that! A classic "how hard can it be" moment.

dp11
Posts: 841
Joined: Sun Aug 12, 2012 8:47 pm
Contact:

Re: Open Source Logic Analyzer Experiments

Post by dp11 » Sun Oct 15, 2017 5:38 am

Actually thinking about it while going back would be great. Just setting the JSR address to the two writes gives the user in the disassembly the clue of where you have come from. Might also be worth checking the address stored with the predicted address when you think you know that the instruction address for consistency?

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sun Oct 15, 2017 7:45 am

dp11 wrote:Actually thinking about it while going back would be great. Just setting the JSR address to the two writes gives the user in the disassembly the clue of where you have come from. Might also be worth checking the address stored with the predicted address when you think you know that the instruction address for consistency?
Yes, this would be more manageable and still quite useful.

Thinking more generally, the PC prediction will initialize when one of these encountered:
- an interrupt (BRK, IRQ, NMI, RST)
- a JSR
- a JMP
- a RTS
- a RTI

So it's only in the first two cases that back tracing can be used (only these stack the address of where they came from).

So even with a lot of work, it would never be perfect.

Dave

User avatar
1024MAK
Posts: 8009
Joined: Mon Apr 18, 2011 4:46 pm
Location: Looking forward to summer in Somerset, UK...
Contact:

Re: Open Source Logic Analyzer Experiments

Post by 1024MAK » Sun Oct 15, 2017 8:58 am

Thank you Dave and Ed, some excellent work there =D> =D> =D>

I will have to dig out my Open Bench Logic Sniffer again and have a play :mrgreen:

Mark

User avatar
BigEd
Posts: 2140
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Open Source Logic Analyzer Experiments

Post by BigEd » Sun Oct 15, 2017 9:41 am

hoglet wrote:
dp11 wrote:Actually thinking about it while going back would be great. Just setting the JSR address to the two writes gives the user in the disassembly the clue of where you have come from. Might also be worth checking the address stored with the predicted address when you think you know that the instruction address for consistency?
Yes, this would be more manageable and still quite useful.

Thinking more generally, the PC prediction will initialize when one of these encountered:
- an interrupt (BRK, IRQ, NMI, RST)
- a JSR
- a JMP
- a RTS
- a RTI

So it's only in the first two cases that back tracing can be used (only these stack the address of where they came from).

So even with a lot of work, it would never be perfect.

Dave
There is one case which could be straightforward and should be useful: if the PC is presently unknown, and you're about to write the annotation for a JSR or an interrupt. The current PC is, suddenly and at the last minute, known!

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sun Oct 15, 2017 9:58 am

BigEd wrote: There is one case which could be straightforward and should be useful: if the PC is presently unknown, and you're about to write the annotation for a JSR or an interrupt. The current PC is, suddenly and at the last minute, known!
Agreed, and I will add that this morning.

Dave

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Sun Oct 15, 2017 5:38 pm

I've done a few more bits and bobs on this today.

I've sorted the unreliability (hanging) I was seeing with the Cypress CY7C68013A development board. It turned out that the sigrok fx2lafw firmware image I had built was faulty. Why? Because the 8051 assembler on Ubuntu 14.04 (SDCC 3.3) has a bug that causes macros to be silently ignored. Using one of the pre-built binary firmware images sorted this.

So I'm now able to use this board as a 16 channel logic analyzer sampling @ 12MHz and it seems very robust and able to do very long captures. The limiting factor then becomes the software.

I've also implemented the change suggested earlier by Dominic and Ed, which was to make use of the address pushed onto the stack by JSR and the various interrupts. This improved the PC value prediction and allows some sanity checking:
https://github.com/hoglet67/libsigrokde ... 98351e?w=1

The last thing to report is that yesterday Ed pointed out that the 6502 annotations seemed to lag the bus signals by one cycle. So the Fetch cycle didn't actually line up with SYNC being high. This was also causing the wrong cycle to appear stretched when RDY is taken low.

You can see the original issue here:
sigrok6.png
Look at the STA FE8E instruction - it should the the Write cycle that is stretched not Op2.

This is now fixed:
sigrok20.png
Do give me a shout if you want to give any of this a try.

Dave

P.S. For any Z80 folk, there already is a Z80 protocol decoder included in sigrok.

User avatar
1024MAK
Posts: 8009
Joined: Mon Apr 18, 2011 4:46 pm
Location: Looking forward to summer in Somerset, UK...
Contact:

Re: Open Source Logic Analyzer Experiments

Post by 1024MAK » Sun Oct 15, 2017 5:54 pm

hoglet wrote:The last thing to report is that yesterday Ed pointed out that the 6502 annotations seemed to lag the bus signals by one cycle. So the Fetch cycle didn't actually line up with SYNC being high.
That explains why it did not conform to my expectations of how a 6502 works and why there was a bit of puzzled head scratching going on when I was reading the thread this morning....

Mark

User avatar
BigEd
Posts: 2140
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Open Source Logic Analyzer Experiments

Post by BigEd » Sun Oct 15, 2017 6:07 pm

This is an excellent thing Dave!

User avatar
BigEd
Posts: 2140
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Open Source Logic Analyzer Experiments

Post by BigEd » Mon Oct 30, 2017 9:11 am

Featured on Hackaday, Dave - congratulations!

There's a comment there about the cost of a 40 pin DIP test clip - £40 maybe - but I see some for under £20 on ebay. Think they'd be any good?

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Mon Oct 30, 2017 9:18 am

BigEd wrote: There's a comment there about the cost of a 40 pin DIP test clip - £40 maybe - but I see some for under £20 on ebay. Think they'd be any good?
These turn up regularly for about £20.

I can vouch for the 3M one as I have a 28-pin one of these.

Not heard of the second one, K&H, before.

The AP one is a decent brand as well, but the connections at the top don't look like they would take a standard jumper lead.

Dave

User avatar
hicks
Posts: 84
Joined: Fri Sep 29, 2017 10:39 am
Location: UK
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hicks » Mon Oct 30, 2017 9:53 am

Nice work on the decoder and the detailed write-up =D>

I've been considering getting a logic analyser for a while now rather than making do with a 4 channel scope as a substitute. Now have a starting point :)

User avatar
hicks
Posts: 84
Joined: Fri Sep 29, 2017 10:39 am
Location: UK
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hicks » Mon Oct 30, 2017 11:11 am

hoglet wrote:I should say that the Open Bench Logic Sniffer supports 32 channels, but most cheap logic analyzers only have 16 channels, so I wanted to see how useful these are. Crucially, this does not allow the address bus to be captured.
May be a daft idea, but out of interest, would it be feasible to use two logic analysers with a few shared signals to capture traces, assuming you can then use a utility to find a unique synchronisation point to align the two separate traces, save the combined result and then load it into sigrok for analysis?

As the cost seems to shoot up once you start going for more channels whilst maintaining a good sample rate and for some projects being able to monitor several chips at once would be quite useful.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Mon Oct 30, 2017 12:35 pm

hicks wrote: May be a daft idea, but out of interest, would it be feasible to use two logic analysers with a few shared signals to capture traces, assuming you can then use a utility to find a unique synchronisation point to align the two separate traces, save the combined result and then load it into sigrok for analysis?
I think the problem then becomes USB bus bandwidth, i.e. you would have to make sure they were attached to different USB controllers.

Dave

Prime
Posts: 2579
Joined: Sun May 31, 2009 11:52 pm
Contact:

Re: Open Source Logic Analyzer Experiments

Post by Prime » Tue Nov 07, 2017 12:42 pm

Hi All,

Following Dave's instructions I've managed to get sigrock up and running under windows, but wanted to try and merge in his changes to the OLS driver as I actually have this board and it would be useful to be able to set a trigger condition :) Though I do have one of the Cypress boards on order as that seems to be able to capture for longer which may be significant in my usage case :)

Problem is trying to compile Dave's changes for use on Windows is a pain in the butt! You have to cross compile from Linux (not a problem in itself), but the only way I could get the crosscompile environment setup was to install a virtual ubuntu image on vmplayer :) (my Linux boxes are all Suse, and the work ones are Centos, tried installing mxe on there and couldn't get it to work correctly). Anyway it seems to build the command line and library parts ok, but falls over trying to build the pulseview :(

So Dave any chance you could submit your patches to the sigrock project that way they'll make it into the nightly builds......

Cheers,

Phill.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Tue Nov 07, 2017 1:00 pm

Hi Phill,
Prime wrote: So Dave any chance you could submit your patches to the sigrock project that way they'll make it into the nightly builds......
The OLS driver is a bit of a can of worms...

The problem is there are several different firmware versions for the Open Bench Logic Sniffer, and I don't believe my changes are backwards compatible. In fact, I know they aren't as they rely on new functionality (that I pulled in from the Pipistrello driver). Remember, I'm using the Papilio One rather than the original Logic Sniffer.

So if these were submitted upstream in their current state then they would break lots of people's setups, your's included I think.

You should be able to use the existing OLS driver with he 6502 Protocol Decoder.

Specifically, what feature OLS feature are you wanting to use that is missing?

Dave

User avatar
fordp
Posts: 965
Joined: Sun Feb 12, 2012 9:08 pm
Location: Kent, England
Contact:

Re: Open Source Logic Analyzer Experiments

Post by fordp » Wed Nov 08, 2017 1:28 pm

FordP (Simon Ellwood)
Time is an illusion. Lunchtime, doubly so!

Prime
Posts: 2579
Joined: Sun May 31, 2009 11:52 pm
Contact:

Re: Open Source Logic Analyzer Experiments

Post by Prime » Fri Nov 10, 2017 4:50 pm

Dave,

Which driver are you using for your LCsoft board? I used fx2lafw-cypress-fx2.ihx which was what the sigrok page suggested, but I see in your screenshots that it's listed as "sigrok FX2 (16ch)" and in mine as "Cypress FX2".

Also is there anything wacky about the order of the inputs are PB0..7 on the board D0..7 in pulseview, and likewise PD0..7 are D8..15?

Cheers.

Phill.

User avatar
hoglet
Posts: 7610
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Open Source Logic Analyzer Experiments

Post by hoglet » Fri Nov 10, 2017 5:15 pm

Hi Phill,
Prime wrote:Which driver are you using for your LCsoft board? I used fx2lafw-cypress-fx2.ihx which was what the sigrok page suggested, but I see in your screenshots that it's listed as "sigrok FX2 (16ch)" and in mine as "Cypress FX2".
I'm not sure how it works on Windows, but on Linux libsigrok loads the firmware into the Cypress FX2 when the device is first used (e.g. when you run sigrok-cli or pulseview).

It chooses the firmware based on the USB ID in this hard-coded table:
https://github.com/hoglet67/libsigrok/b ... /api.c#L92

With J1 fitted on the LCSOFT board it appears as USB ID 1d50:608d which loads the "fx2lafw-sigrok-fx2-16ch" firmware.

With J1 not fitted on the LCSOFT board it appears as USB ID 04b4:8613 which loads the "fx2lafw-cypress-fx2" firmware.

I'm using the first of these, haven't tried the second. I'm not sure what the difference is. Looking at the firmware sources, they seem identical apart from the USB ID and the product name. Both are the sigrok fx2la open source firmware.

I think on Linux the 04b4:8613 USB ID is linked to an existing kernel driver ('usbtest'), so can be problematic.
Prime wrote: Also is there anything wacky about the order of the inputs are PB0..7 on the board D0..7 in pulseview, and likewise PD0..7 are D8..15?
Yes, that right. Nothing wacky in this case.

There's an update on the protocol decoder here:
http://forum.6502.org/viewtopic.php?p=57164#p57164

The latest version (on a branch as it's still being tweaked) also tries to predict the current register state:

Code: Select all

 DC0B: LDX F4        A=80 X=03 Y=0F SP=F1 N=0 V=0 D=0 I=1 Z=0 C=1
 DC0D: STY F4        A=80 X=03 Y=0F SP=F1 N=0 V=0 D=0 I=1 Z=0 C=1
 DC0F: STY FE30      A=80 X=03 Y=0F SP=F1 N=0 V=0 D=0 I=1 Z=0 C=1
 DC12: LDY #00       A=80 X=03 Y=00 SP=F1 N=0 V=0 D=0 I=1 Z=1 C=1
 DC14: LDA (F6),Y    A=01 X=03 Y=00 SP=F1 N=0 V=0 D=0 I=1 Z=0 C=1
 DC16: STX F4        A=01 X=03 Y=00 SP=F1 N=0 V=0 D=0 I=1 Z=0 C=1
 DC18: STX FE30      A=01 X=03 Y=00 SP=F1 N=0 V=0 D=0 I=1 Z=0 C=1
 DC1B: RTS           A=01 X=03 Y=00 SP=F3 N=0 V=0 D=0 I=1 Z=0 C=1
 B8AE: STA BD        A=01 X=03 Y=00 SP=F3 N=0 V=0 D=0 I=1 Z=0 C=1
 B8B0: PLA           A=0F X=03 Y=00 SP=F4 N=0 V=0 D=0 I=1 Z=0 C=1
 B8B1: PHA           A=0F X=03 Y=00 SP=F3 N=0 V=0 D=0 I=1 Z=0 C=1
 B8B2: TAY           A=0F X=03 Y=0F SP=F3 N=0 V=0 D=0 I=1 Z=0 C=1
 B8B3: LDA BD        A=01 X=03 Y=0F SP=F3 N=0 V=0 D=0 I=1 Z=0 C=1
 B8B5: EOR #FF       A=FE X=03 Y=0F SP=F3 N=1 V=0 D=0 I=1 Z=0 C=1
 B8B7: JSR B745      A=FE X=03 Y=0F SP=F1 N=1 V=0 D=0 I=1 Z=0 C=1
 B745: STA BF        A=FE X=03 Y=0F SP=F1 N=1 V=0 D=0 I=1 Z=0 C=1
...
irrelevant stuff deleted
...
 B765: LDA BF        A=FE X=03 Y=0F SP=EF N=1 V=0 D=0 I=1 Z=0 C=1
 B767: JSR B771      A=FE X=03 Y=0F SP=ED N=1 V=0 D=0 I=1 Z=0 C=1
 B771: JMP (00B0)    A=FE X=03 Y=0F SP=ED N=1 V=0 D=0 I=1 Z=0 C=1
 2000: STY F4        A=FE X=03 Y=0F SP=ED N=1 V=0 D=0 I=1 Z=0 C=1
 2002: STY FE30      A=FE X=03 Y=0F SP=ED N=1 V=0 D=0 I=1 Z=0 C=1
 2005: LDY #00       A=FE X=03 Y=00 SP=ED N=0 V=0 D=0 I=1 Z=1 C=1
 2007: STA (BA),Y    A=01 X=03 Y=00 SP=ED N=0 V=0 D=0 I=1 Z=1 C=1 prediction failed
 
Dave

Post Reply