B-Em Debugging/Tracing

want to talk about MESS/model b/beebem/b-em/electrem/elkulator? do it here!
Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

B-Em Debugging/Tracing

Postby Coeus » Sat Mar 11, 2017 3:24 pm

fordp2002 mentioned instruction tracing and disassembly for the 32016. Not for the first time I thought it should be possible to use a common debugger core with more than one processor type. That should be a quick win for bringing debugging to the non-6502 processors and also means that if someone fancies writing a fancy GUI debugger in the future it only needs to be done once. Obviously for that to work the CPU modules have to provide some hooks/info for the debugger so I though maybe this would suffice:

Code: Select all

typedef struct {
    const char *cpu_name;                                            // Name/model of CPU.
    int debug_enable(int newvalue)                                   // enable/disable debugging on this CPU, returns previous value.
    uint32_t memread(uint32_t addr);                                 // CPU's usual memory read function for data.
    uint32_t memfetch(uint32_t addr);                                // as above but for instructions.
    void memwrite(uint32_t addr, uint32_t value);                    // CPU's usual memory write function.
    uint32_t disassemble(uint32_t addr, char *buf, size_t bufsize);  // disassemble one line, returns next address
    const char **reg_names;                                          // NULL pointer terminated list of register names.
    uint32_t reg_get(int which);                                     // Set a register - which is the index into the names above
    void reg_set(int which, uint32 value);                           // Set a register.
    size_t *reg_print(int which, char *buf, size_t bufsize);         // Print register value in CPU standard form.
    void reg_parse(int which, char *strval);                         // Parse a value into a register.
} cpu_debug_t;


That is deliberately described as a structure for when a CPU calls the debugger it can pass it as one argument and the debugger can make use of those functions without having to have any logic to work out which CPU it is debugging and then have to choose the right set of statically named functions. This obviously delegates instruction disassembly to the CPU module (or a parallel helper module) but also register value printing and parsing to enable that module to also do things such as expanding CPU flags to symbolic notation and because the CPU knows the width of its own registers whereas this interface is 32bit throughout. That would then have to be complimented by the debugger providing some functions:

Code: Select all

uint32_t debug_memread(cpu_debug_t *cpu, uint32_t addr);
uint32_t debug_memfetch(cpu_debug_t *cpu, uint32_t addr);
void debug_memwrite(cpu_debug_t *cpu, uint32_t addr, uint32_t value);


These would be called by the CPU in place of its usual memory access function. I don't know if we have CPUs that separate memory fetches for instructions/data so if not we could dispense with that distinction. The intention is that the debugger would then call back usual memory read/write function from the structure above thus avoiding the need for separate hooks for pre/post. Finally:

Code: Select all

void debug_preexec(cpu_debug_t *cpu, uint32_t addr);

For tracing, single-stepping etc.

What do you guys think?

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

Re: B-Em Debugging/Tracing

Postby hoglet » Sat Mar 11, 2017 3:42 pm

That looks a good starting point. I'd not thought about pushing down the register printing side, but that makes sense.

I think this would work in PiTubeDirect as well. I was imagining in that context you interact with the debugger over the serial port.

What's not 100% clear to me is the sequence of interactions between the CPU core and the application (B-Em, PiTubeDirect, etc) to enable debugging and single step a few instructions.

Do you think you could sketch out the sequence function calls?

How does it (the application) get hold of a core's cpu_debug_t structure?

It would then start by calling cpu_debug->debug_enable(1).

How would it then single step 10 instructions (with disassembly)?

Dave

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

Re: B-Em Debugging/Tracing

Postby fordp » Sat Mar 11, 2017 4:48 pm

I love the idea in principle. I had a similar idea but I was going to look a how gdb remote debugging worked as if we make it compatible with that then we would get a lot for free. gdb can of course work over a serial port.

I will do some digging.
FordP (Simon Ellwood)
Time is an illusion. Lunchtime, doubly so!

User avatar
simonm
Posts: 166
Joined: Mon May 09, 2016 2:40 pm
Contact:

Re: B-Em Debugging/Tracing

Postby simonm » Sat Mar 11, 2017 6:45 pm

I'm also interested in this topic. I wrote an extension for using BeebAsm in Visual Studio Code, but I saw that VSC also supports a remote debugger architecture too, so getting a BeebAsm/B-Em compiler/debugger workflow all integrated in VSC would be very cool.
https://code.visualstudio.com/docs/exte ... -debuggers
https://marketplace.visualstudio.com/it ... m.beeb-vsc

Cheers
Simon

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

Re: B-Em Debugging/Tracing

Postby fordp » Sat Mar 11, 2017 8:43 pm

simonm wrote:I'm also interested in this topic. I wrote an extension for using BeebAsm in Visual Studio Code, but I saw that VSC also supports a remote debugger architecture too, so getting a BeebAsm/B-Em compiler/debugger workflow all integrated in VSC would be very cool.
https://code.visualstudio.com/docs/exte ... -debuggers
https://marketplace.visualstudio.com/it ... m.beeb-vsc

Cheers
Simon


This looks great I hope we can get all this working.
FordP (Simon Ellwood)
Time is an illusion. Lunchtime, doubly so!

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Sat Mar 11, 2017 10:15 pm

I had a quick look at the VS debuggers page linked above. I didn't find anything which seemed liked protocol documentation. Perhaps I need to work through it again when I have more time. The obvious question this raises is whether implementing a remote debug protocol for VS is a different or complimentary thing to trying to consistent internal API with B-em for debugging?

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

Re: B-Em Debugging/Tracing

Postby fordp » Sat Mar 11, 2017 10:15 pm

I just installed VS Code on my Ubuntu Linux machine. Looks interesting. I will do some more playing.
FordP (Simon Ellwood)
Time is an illusion. Lunchtime, doubly so!

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

Re: B-Em Debugging/Tracing

Postby fordp » Sat Mar 11, 2017 10:16 pm

Coeus wrote:I had a quick look at the VS debuggers page linked above. I didn't find anything which seemed liked protocol documentation. Perhaps I need to work through it again when I have more time. The obvious question this raises is whether implementing a remote debug protocol for VS is a different or complimentary thing to trying to consistent internal API with B-em for debugging?


Says it supports gdb.
FordP (Simon Ellwood)
Time is an illusion. Lunchtime, doubly so!

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Sat Mar 11, 2017 10:24 pm

fordp wrote:
Coeus wrote:Says it supports gdb.


So that comes back to the earlier question of how to make B-em support the gdb protocol.

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Sat Mar 11, 2017 10:25 pm

fordp wrote:I just installed VS Code on my Ubuntu Linux machine. Looks interesting. I will do some more playing.


That's interesting. I'm on Arch and that seem to have an AUR package for VS Code too.

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

Re: B-Em Debugging/Tracing

Postby hoglet » Sat Mar 11, 2017 10:36 pm

Coeus wrote:The obvious question this raises is whether implementing a remote debug protocol for VS is a different or complimentary thing to trying to consistent internal API with B-em for debugging?

The GDB remote debug protocol seems to be almost a CLI interface onto a debugger:
https://sourceware.org/gdb/onlinedocs/g ... ml#Packets

If that's the case, then it's definitely complementary to what you are proposing each core implemented.

I could imagine a common remote debug module that sat on top of the API you proposed and implemented the GDB remote debug protocol. This would then work with any CPU core. But this would be quite a lot of work, as the GDB remote debug protocol seems quite complicated, and it's not clear how little you could get away with.

This link seems a bit easier to understand:
http://www.embecosm.com/appnotes/ean4/e ... #id3033520

Dave

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Sat Mar 11, 2017 11:01 pm

hoglet wrote:How would it then single step 10 instructions (with disassembly)?


Dave, I realised I hadn't addresses the question of getting the cpu_debug_t structure. In B-Em which doesn't really support multiple instances of anything it would be possible to just have an array of these. It would probably still be better for the actual definition to live in the CPU module concerned and the debugger could then have an array of pointers with a NULL to indicate the end of the list. That means responding to command to enable/disable debugging or a command line option to do the same it could search this array, check the name and called the debug_enable function for the appropriate CPU. That doesn't address dynamically loadable CPUs - is that a feature of PiTubeDirect?

That does mean there would have to be separate structures for the main (I/O) 6502 and the tube 6502 though they could share the disassemble function.

So my thinking was that CPU would either be in debug mode or free run mode. When in debug mode it would call the debug_ functions instead of its native ones. So as an example, assume running this on the core 6502 and b-em has just been started with the -debug flag so the sequence should be:

debugger finds cpu_debug_t core 6502 in table of processors.
debugger calls debug_enable(1) on that 6502.
6502 calls debug_memread(cpu, 0xfffc)
debugger checks for "break on read" for that address - finds none.
debugger calls cpu->memread(0xfffc) and returns the return value from that as the return value from debug_memread
repeat the three lines above for the byte of the start address (0xfffd)
6502 calls debug_preexec(cpu, 0xe364) (this is on a master)
debugger starts in single step mode so calls cpu->dissassemble(0xe364, ...) and prints the disassembled instruction and waits for a command.
Let's assume the user asks to trace 10 instructions - debugger keeps this count internally and returns from debug_preexec.
So the next nine iterations go something like:
CPU calls debug_memfetch to fetch the opcode.
debugger checks for "break on read" for the instruction address - finds none, calls cpu->memfetch and returns its return value.
CPU calls debug_memfetch for any immediate operand/address/offset
same checks as for opcode.
CPU calls debug_memread for any memory operand
debugger checks for "break on read" for the data address - finds none, calls cpu->memread and returns its return value.
If result is to go back to memory rather than a register, CPU calls debug_writeread(cpu, ...)
debugger checks for "break on write", finds none, calls cpu->memwrite.
CPU moves on to the next instruction, calls debug_preexec again.
debugger calls cpu->disassemble, prints result.
debugger calls cpu->reg_print for each register and prints result.
debugger decrements count, not zero, returns from debug_preexec
the tenth iteration is obviously similar but debug_preexec will cause the debugger to prompt for what to do next.

The intention of the debug_memread/debug_memfetch/debug_memwrite functions is that the debugger can implement breakpoints on memory reads/write which could check only the address being read/written to or could check the value read/written too. Something similar could be done with post-read, where the CPU provides both the address and the value read, and pre-write, where the CPU provides the address and the value due to be written, but post-read in particular doesn't allow a breakpoint just before an I/O register is read which might have side effects such as clearing a pending interrupt etc.

Thinking of I/O it occurs to me the Z80 has a separate I/O address space. That could be accommodated by a couple of IO port functions similar to the memory ones. CPUs that don't use these could leave them NULL.

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

Re: B-Em Debugging/Tracing

Postby fordp » Sat Mar 11, 2017 11:37 pm

hoglet wrote:But this would be quite a lot of work, as the GDB remote debug protocol seems quite complicated, and it's not clear how little you could get away with.

This link seems a bit easier to understand:
http://www.embecosm.com/appnotes/ean4/e ... #id3033520

Dave


This is a lot easier to implement on a softcore than a real chip. I think it would be much easier to use this API than dream up a new one. I suspect a lot of the features are not used or needed.
FordP (Simon Ellwood)
Time is an illusion. Lunchtime, doubly so!

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Sun Mar 12, 2017 12:01 am

fordp wrote:This is a lot easier to implement on a softcore than a real chip. I think it would be much easier to use this API than dream up a new one. I suspect a lot of the features are not used or needed.


Having had a very quick peruse of the document Dave linked it seems to me to be worthwhile to see whether the Standard Remote Debugging part of the protocol could be implemented. Also, looking at typical commands I think I come to the same conclusion as Dave that what I started this with is not really an alternative to the GDB protocol that would work alongside it. The GDB protocol assumes the target being debugged holds some state about the debugging itself, i.e. break/trace points etc. and I was proposing to centralise that so the only state any one CPU module has to keep about being debugged is whether debugging is happening on that CPU or not. What I am proposing is obviously not necessary to implement the GDB protocol - each CPU module could so it directly, but I think it would save some work.

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

Re: B-Em Debugging/Tracing

Postby hoglet » Sun Mar 12, 2017 2:12 pm

Steve,

Thanks for that detailed walk-through - I think a first prototype based on that would be excellent.

PiTubeDirect doesn't dynamically instantiate CPUs. They are all statically linked. Only one is active at once.

It does seem like an initialisation method would be needed in each core, e.g.
cpu_debug_t *ns32016_core_init();
I can't see how else you could do it really.

And probably a similar destroy method.

Dave

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

Re: B-Em Debugging/Tracing

Postby hoglet » Tue Mar 14, 2017 11:56 am

Hi Guys,

A quick update on what I messing with at the moment....

I've just started some prototyping of a co-processor debug interface, based on Steve's proposal above, in PiTubeDirect (in a branch called debugger).

I've added an interrupt-driven serial port interface to PiTubeDirect. This routes any received characters to a very simple debug command processor, is loosely modelled on the command line interface to ICE-T65:
https://github.com/hoglet67/AtomBusMon/ ... -Reference
(which in turn drew ideas from the debugger in B-em).

The next step is to try to build out an implementation of Steve's debug interface for one of the Co Processors. I intend to start with the NS32K, as it's also relevant to B-Em, and we also already have the disassembler that Simon wrote last year.

Building this from the ground up should be a good way to validate the proposed debug interface is sufficient.

I'll post another update later in the week as and when I have something useful working.

Dave

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

Re: B-Em Debugging/Tracing

Postby hoglet » Tue Mar 14, 2017 4:33 pm

Steve,

I've hit the first stumbling block with the cpu_debug_t interface.

The 32016 Co Pro has multiple memory accessors for different width accesses:

Code: Select all

uint8_t read_x8(uint32_t addr);
uint16_t read_x16(uint32_t addr);
uint32_t read_x32(uint32_t addr);
uint64_t read_x64(uint32_t addr);

void write_x8(uint32_t addr, uint8_t val);
void write_x16(uint32_t addr, uint16_t val);
void write_x32(uint32_t addr, uint32_t val);
void write_x64(uint32_t addr, uint64_t val);

How do you think we should handle these?

One simple answer is in debug mode to have the them all map down to read_x8()/write_x8(), and that's the only thing the debug interface knows about.

Dave

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Tue Mar 14, 2017 5:37 pm

Dave, that's one solution and it may be the best one. Just checking NS32016/mem32016.c that looks like just behaving like slow ram mode rather than fast ram mode.

There are others options:

1. Pass the real memory access function as one argument of debug_mem_read/debug_mem_write etc. The snag with that is the debugger needs to be clean for whatever the maximum width is and if these are declared with different return types we defeat that with a pointer cast we could hit issues with whether widening has been applied or not.

2. Increase the number of real read/write functions in cpu_debug_t to include different widths and 8/16bit processors will just leave these ones NULL.

3. Go back to post-read/pre-write hooks where the debugger has a hook function that takes the maximum width and widening happens within the CPU module which does the actual read/write.

I haven't started on any of the 8 bit processors yet so no harm in any redesign from my perspective. What do you reckon?

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

Re: B-Em Debugging/Tracing

Postby fordp » Tue Mar 14, 2017 5:56 pm

I spotted that issue with the proposed interface. I would just have an arbitrary size interface. The other advice is to revert to what gdb does. What can you request via gdb?

bool ReadMemory(unsigned long Address, void* pDestination, unsigned long Size);

With Dominic's new design on PiDirect this call could be shared across all the CoPro's :D
FordP (Simon Ellwood)
Time is an illusion. Lunchtime, doubly so!

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

Re: B-Em Debugging/Tracing

Postby hoglet » Tue Mar 14, 2017 8:07 pm

Coeus wrote:Dave, that's one solution and it may be the best one. Just checking NS32016/mem32016.c that looks like just behaving like slow ram mode rather than fast ram mode.

There are others options:

1. Pass the real memory access function as one argument of debug_mem_read/debug_mem_write etc. The snag with that is the debugger needs to be clean for whatever the maximum width is and if these are declared with different return types we defeat that with a pointer cast we could hit issues with whether widening has been applied or not.

2. Increase the number of real read/write functions in cpu_debug_t to include different widths and 8/16bit processors will just leave these ones NULL.

3. Go back to post-read/pre-write hooks where the debugger has a hook function that takes the maximum width and widening happens within the CPU module which does the actual read/write.

I haven't started on any of the 8 bit processors yet so no harm in any redesign from my perspective. What do you reckon?

I think for now I'd like to try and get everything working with the _x8 functions, then maybe have a think about whether read/write hooks pattern would be simpler.
fordp wrote:I spotted that issue with the proposed interface. I would just have an arbitrary size interface. The other advice is to revert to what gdb does. What can you request via gdb?

bool ReadMemory(unsigned long Address, void* pDestination, unsigned long Size);

I need to think about this some more. The implication I think is that in "debug" mode, mem3216 would have to route all accesses via a single variable size memory accessor that's in the debugger, and then the debugger routes this back to a similar method on cpu_debug_d.

It's still quite a lot of change.
fordp wrote:With Dominic's new design on PiDirect this call could be shared across all the CoPro's :D

We probably shouldn't assume that all Co Processors work in that way.

Anyway, I think we also need to deal with accesses to the Tube registers.

This is where I've got to so far.

Code: Select all

>> help
PiTubeDirect debugger; cpu = 32016
Commands:
    help
    regs
    dis
    fill
    crc
    mem
    rdm
    wrm
>> regs
      R0 = 00000000
      R1 = 00000000
      R2 = 000ff9b4
      R3 = 0000000e
      R4 = 00000000
      R5 = 00000000
      R6 = 00000000
      R7 = 00000000
      PC = 00f00a25
      SB = 000ffdbc
     SP0 = 00000000
     SP1 = 00000000
      FP = 00000000
 INTBASE = 000ffe64
     MOD = 0020
     PSR = xxxx10000010x000
     CFG = 00000002
>> dis f00a25
&F00A25 [1C76A814] F4 MOVB    @x'FFFFFFF6,R0
&F00A28 [0C7A001C] F2 CMPQB   0,R0
&F00A2A [D05F0C7A] F0 BLE     &F00A36
&F00A2C [E714D05F] F2 MOVQD   0,20(SB)
&F00A2F [18BFDDE7] F4 ADDRD   * + -232,TOS
&F00A33 [1791BCEA] F0 BR      &F006C4
&F00A36 [1C005017] F4 MOVD    0(R2),R0
&F00A39 [7A74A81C] F2 CMPQB   0,@x'FFFFFFF4
&F00A3C [AA147D7A] F0 BLE     &F00A39
&F00A3E [0076AA14] F4 MOVB    @x'FFFFFFF6,0(R0)
>> mem ffdbc
FFDBC 44 00 F0 00 00 00 00 00 00 00 00 00 00 80 00 00  D...............
FFDCC 00 80 00 00 C7 06 F0 00 B0 FD 0F 00 BC F9 0F 00  ................
FFDDC 01 EF CD AB AE 0D F0 00 80 01 01 00 00 00 00 00  ................
FFDEC 00 01 00 00 00 00 10 00 44 42 3D 30 00 00 00 00  ........DB=0....
FFDFC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
FFE0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
FFE1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
FFE2C 00 00 00 00 20 00 3C 04 20 00 3C 04 20 00 3C 04  .... .<. .<. .<.
FFE3C 20 00 3C 04 20 00 3C 04 20 00 3C 04 20 00 3C 04   .<. .<. .<. .<.
FFE4C 20 00 3C 04 20 00 3C 04 20 00 3C 04 20 00 3C 04   .<. .<. .<. .<.
FFE5C 20 00 3C 04 20 00 3C 04 20 00 DE 03 30 00 00 00   .<. .<. ...0...
FFE6C 20 00 E6 0C 20 00 E9 0C 20 00 EC 0C 20 00 28 06   ... ... ... .(.
FFE7C 20 00 EF 0C 20 00 F2 0C 20 00 F5 0C 20 00 F8 0C   ... ... ... ...
FFE8C 20 00 FB 0C FE FD F2 E0 03 01 FC 07 00 00 00 00   ...............
FFE9C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
FFEAC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
>>

Code is here:
https://github.com/hoglet67/PiTubeDirec ... s/debugger

Next up is enabling the memory hooks, and adding some memory watchpoint commands.

Dave

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

Re: B-Em Debugging/Tracing

Postby dp11 » Tue Mar 14, 2017 10:16 pm

fordp wrote:
With Dominic's new design on PiDirect this call could be shared across all the CoPro's :D

We probably shouldn't assume that all Co Processors work in that way.


I've so far been lazy and not done all the co pros. I don't see any reason why we can't assume they all start at 0x0000 and have no memory pointer.

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

Re: B-Em Debugging/Tracing

Postby fordp » Tue Mar 14, 2017 10:19 pm

I suspect reading tube registers will have side effects so it may be better not to allow access to the tube registers.
FordP (Simon Ellwood)
Time is an illusion. Lunchtime, doubly so!

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Tue Mar 14, 2017 10:40 pm

I have just found another couple of small flaws in the API

1. The disassemble function needs to take a cpu_debug_t as the first argument. As there are two 6502s when the co-pro is a 6502 the disassembler needs to know which one to read the memory of. So now:

2. We need some kind of "read flags" method. This is because there is both a 6502 and 65C02 in use and the disassembler needs to know the difference without having a completely separate on for each. So the new structure becomes:

Code: Select all

typedef struct _cpu_debug cpu_debug_t;

struct _cpu_debug {
    const char *cpu_name;                                               // Name/model of CPU.
    int      (*debug_enable)(int newvalue);                             // enable/disable debugging on this CPU, returns previous value.
    uint32_t (*memread)(uint32_t addr);                                 // CPU's usual memory read function for data.
    uint32_t (*memfetch)(uint32_t addr);                                // as above but for instructions.
    void     (*memwrite)(uint32_t addr, uint32_t value);                // CPU's usual memory write function.
    uint32_t (*disassemble)(cpu_debug_t *cpu, uint32_t addr, char *buf, size_t bufsize);  // disassemble one line, returns next address
    const char **reg_names;                                             // NULL pointer terminated list of register names.
    uint32_t (*reg_get)(int which);                                     // Get a register - which is the index into the names above
    void     (*reg_set)(int which, uint32_t value);                     // Set a register.
    size_t   (*reg_print)(int which, char *buf, size_t bufsize);        // Print register value in CPU standard form.
    void     (*reg_parse)(int which, char *strval);                     // Parse a value into a register.
    uint32_t (*get_cpudep)(cpu_debug_t *cpu);                           // Get some other CPU-dependent value.
};

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

Re: B-Em Debugging/Tracing

Postby hoglet » Tue Mar 14, 2017 10:45 pm

dp11 wrote:I've so far been lazy and not done all the co pros. I don't see any reason why we can't assume they all start at 0x0000 and have no memory pointer.

We'd like to be able to re-use some of these Co Processors in B-Em; so far that's just the 32016.

I doubt that using a chunk of memory starting at zero will work nicely on Windows and Linux.

So a compile time switch is still needed, but we could share a common memory block between cores.

Dave

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Wed Mar 15, 2017 3:23 am

I a post above I did mention extending the API because of some things I had run into with the 6502s sharing a disassembler.

On reflection I don't think those changes are necessary after allm. I can use a small function in each 6502 as the .disassembler field on cup_debug_t and it can then call the actual disassembler with whatever extra arguments I need so there is no need to complicate the API for this special case.

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

Re: B-Em Debugging/Tracing

Postby hoglet » Wed Mar 15, 2017 7:26 am

Steve,

On reflection I'm now thinking that the post-read/pre-write write hooks is actually a much simpler pattern to implement with a complex CPU:

Code: Select all

void debug_memread(cpu_debug_t *cpu, uint32_t addr, uint32_t value, uint8_t size);
void debug_memwrite(cpu_debug_t *cpu, uint32_t addr, uint32_t value, uint8_t size);
void debug_preexec(cpu_debug_t *cpu, uint32_t addr);


This is simpler because:
- it's additive to an existing CPU emulation, rather than needing to re-route all memory accesses via the debugger
- it extends more naturally to different size accesses
- you don't need to design a set of callback methods on cpu_debug_t that capture all possible CPU read/write semantics

I think we can then reduce the methods in cpu_debug_t to be use byte accesses, and drop fetch

Code: Select all

    uint32_t memread(uint32_t addr);                                 // CPU's usual memory read function for data.
    void memwrite(uint32_t addr, uint32_t value);                    // CPU's usual memory write function.

as the main use of these now is to support debugger commands like dumping memory.

When we come to the Z80, I guess we will need to add IO versions of each of the above.

One question: Why pre-write semantics rather post-write? Is that so the debugger could (in principle) intercept a write and modify the value. I'm not convinced this is actually necessary.

Shall I proceed on this basis today?

FYI, the current version of my cpu_debug.h header file is here:
https://github.com/hoglet67/PiTubeDirec ... pu_debug.h

Dave

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

Re: B-Em Debugging/Tracing

Postby fordp » Wed Mar 15, 2017 8:20 am

hoglet wrote:When we come to the Z80, I guess we will need to add IO versions of each of the above

Dave


You can choose to either have separate methods or just overload the addresses say add 16 MB to access IO.

You need to consider paged access as well but that can come later!
FordP (Simon Ellwood)
Time is an illusion. Lunchtime, doubly so!

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Wed Mar 15, 2017 9:17 am

If pre-write/post-read is easier that's fine with me. It does seem less complex for the case or having different sized memory accesses.

Originally, I was thinking a debugger could modify values on the way to/from memory if necessary but the current B-Em debugger doesn't do this and I didn't see anything the gdb remote protocol either that would take advantage of that so there is no point in making things harder to support something that is unlikely to be used.

The other thing it may be worth considering is when an access has some other effect such as causing a piece of memory-mapped hardware to do something. Do we want a break on memory access to break before that happens? if so maybe pre-access in both cases is the answer? I suppose this is less of an issue for tube processors in that the only I/O would be the tube registers but I want to get the core 6502 debugging into the fold so it's not odd man out.

I may not get any more time for this until later so proceed with whatever seems best to you.
Last edited by Coeus on Wed Mar 15, 2017 9:25 am, edited 1 time in total.

Coeus
Posts: 458
Joined: Mon Jul 25, 2016 11:05 am

Re: B-Em Debugging/Tracing

Postby Coeus » Wed Mar 15, 2017 9:25 am

fordp wrote:You can choose to either have separate methods or just overload the addresses say add 16 MB to access IO.


That would be less work . It's not obvious, though how to set a breakpoint there unless a hint is given when debugging is enabled on that processor. That's could be done, of course.

fordp wrote:You need to consider paged access as well but that can come later!


We did have q query from someone a while back on how to set a breakpoint in a particular ROM (on the I/O 6502) and again the current debugger doesn't support that so if you set a breakpoint in the paged ROM area it will break whenever that address is reached whatever ROM it is in. I have not found it a particular problem as long as you don't so something like setting a breakpoint at 8003 so it breaks on every service call to every ROM. Checking where the service call vectors to and setting the breakpoint there is usually sufficient to get around that. I welcome your thoughts on this - is there a way to describe paged access that doesn't become dependent on the particular CPU in question?

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

Re: B-Em Debugging/Tracing

Postby hoglet » Wed Mar 15, 2017 11:11 am

Coeus wrote:If pre-write/post-read is easier that's fine with me. It does seem less complex for the case or having different sized memory accesses.
...
I may not get any more time for this until later so proceed with whatever seems best to you.

The pre-write/post-read did work out more straightforward.

Here's the updated cpu_debug header file:
https://github.com/hoglet67/PiTubeDirec ... pu_debug.h

Dave


Return to “emulators”

Who is online

Users browsing this forum: No registered users and 3 guests