pete-gordon / oricutron

Portable Oric-1/Atmos/Telestrat and Pravetz 8D emulator
http://www.petergordon.org.uk/oricutron/
GNU General Public License v2.0
69 stars 25 forks source link

Feature request: external debugger support #126

Open nekoniaow opened 5 years ago

nekoniaow commented 5 years ago

As mentioned in a post by Chema on the Defence Force forums, it would be very useful to be able to debug emulated Oric code from a full featured debugger (like Visual Studio or GDB) in addition to using Oricutron's internal debugger (cf this post: http://forum.defence-force.org/viewtopic.php?f=22&t=1001&start=90#p15147 and this one: http://forum.defence-force.org/viewtopic.php?p=18359#p18362).

Adding external debugger support can be done relatively easily by using the GDB serial protocol which allows any program to be controlled via a GDB-compatible debugger (Visual Studio supports that protocol for example, as does Visual Studio Code). This would allow people to debug their Oric programs using all the advanced features of their modern IDE debugger. (cf https://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_node/gdb_125.html for details about that protocol).

As an example, a few people have been working on GDB support for the FS-UAE/Win-UAE Amiga emulator (https://github.com/FrodeSolheim/fs-uae/issues/63) with good results and there does not seem to be any reason why this should not be possible with Oricutron.

Advantages:

assinie commented 5 years ago

I think it's not as simple as it sounds.

You can't use GDB because GDB knows nothing about the 6502 CPU. You can use it with FS-UAE/Win-UAE because the 68K is known by GDB.

It's not because you use the GDB protocol that the external debugger magically knows the 6502 CPU.

I think there are 2 different things

So, if you want use GDB as the debugger, you need to patch GDB in order to support the 6502. Same for Visual Studio. If you want to add some windows to display the video memory (text mode or hires mode), you need to add a plugin to Visual Studio too (and maybe extends the GDB protocol)

Maybe we can see how to add the GDB protocol to Oricutron. But this is only the "easy" part of the work, you still have to find, or program, the right debugger and the tools needed to translate cc65 object file.

nekoniaow commented 5 years ago

I think it's not as simple as it sounds.

Oh, it is not simple, I only said "relatively easily", everything is in the "relatively". ;)

You can't use GDB because GDB knows nothing about the 6502 CPU. You can use it with FS-UAE/Win-UAE because the 68K is known by GDB. It's not because you use the GDB protocol that the external debugger magically knows the 6502 CPU.

You are absolutely right. I wanted to post about similar efforts in my request but my post was long enough. Here are a few other platforms for which this was done:

I think there are 2 different things

  • The external debugger [snip]
  • The protocol between Oricutron and the external debugger
    • This may be GDB protocol or not.

I agree with your analysis and think going for a GDB based approach has very useful advantages:

So, if you want use GDB as the debugger, you need to patch GDB in order to support the 6502.

Yup, absolutely.

Same for Visual Studio.

I am not too sure since I have not read the docs but VS seems to use a dedicated version of GDB, so one probably only needs to port the 6502 support to that version so the effort could be very small (this needs to be verified).

If you want to add some windows to display the video memory (text mode or hires mode), you need to add a plugin to Visual Studio too (and maybe extends the GDB protocol)

On the Oric this is not necessary since video memory is just regular CPU RAM, exposing memory is more than enough and that would be provided by a basic implementation of the GDB protocol.

Maybe we can see how to add the GDB protocol to Oricutron. But this is only the "easy" part of the work, you still have to find, or program, the right debugger and the tools needed to translate cc65 object file.

Indeed, which is why it is "relatively" easy, not just "easy". ;) Ok, "reasonably doable" is probably better. ;)

assinie commented 5 years ago

There is a compile-time option: DEBUG_CPU_TRACE

With this option, a call to mon_traceinst() is made from the m6502_inst() function. Right now, mon_traceinst() fills a circular buffer with the cpu state, romdis and instruction code. This buffer is dumped to a log file when Oricutron exits.

A first step may be to modify mon_traceinst() to send the data to a network socket.

assinie commented 5 years ago

Correction: The circular buffer is actually sent to stdout, not to a log file. Example:

              F4EC  28        PLP                           ---B---- A=03 X=38 Y=03 SP=01EB ROMDIS=0
              F4ED  68        PLA                           ---B--Z- A=03 X=38 Y=03 SP=01EC ROMDIS=0
              F4EE  60        RTS                           ---B--Z- A=00 X=38 Y=03 SP=01ED ROMDIS=0
              EE65  8A        TXA                           ---B--Z- A=00 X=38 Y=03 SP=01EF ROMDIS=0
              EE66  10 03     BPL $EE6B                     ---B---- A=38 X=38 Y=03 SP=01EF ROMDIS=0
              EE6B  A9 01     LDA #$01                      ---B---- A=38 X=38 Y=03 SP=01EF ROMDIS=0
              EE6D  20 9D EE  JSR GetTimer                  ---B---- A=01 X=38 Y=03 SP=01EF ROMDIS=0
GetTimer      EE9D  48        PHA                           ---B---- A=01 X=38 Y=03 SP=01ED ROMDIS=0
              EE9E  0A        ASL                           ---B---- A=01 X=38 Y=03 SP=01EC ROMDIS=0
              EE9F  A8        TAY                           ---B---- A=02 X=38 Y=03 SP=01EC ROMDIS=0
              EEA0  78        SEI                           ---B---- A=02 X=38 Y=02 SP=01EC ROMDIS=0
              EEA1  B9 72 02  LDA $0272,Y                   ---B-I-- A=02 X=38 Y=02 SP=01EC ROMDIS=0
              EEA4  BE 73 02  LDX $0273,Y                   ---B-I-- A=09 X=38 Y=02 SP=01EC ROMDIS=0
              EEA7  58        CLI                           ---B-IZ- A=09 X=00 Y=02 SP=01EC ROMDIS=0
              EEA8  A8        TAY                           ---B--Z- A=09 X=00 Y=02 SP=01EC ROMDIS=0
              EEA9  68        PLA                           ---B---- A=09 X=00 Y=09 SP=01EC ROMDIS=0
              EEAA  60        RTS                           ---B---- A=01 X=00 Y=09 SP=01ED ROMDIS=0
              EE70  C0 00     CPY #$00                      ---B---- A=01 X=00 Y=09 SP=01EF ROMDIS=0
              EE72  D0 12     BNE $EE86                     ---B---C A=01 X=00 Y=09 SP=01EF ROMDIS=0
              EE86  68        PLA                           ---B---C A=01 X=00 Y=09 SP=01EF ROMDIS=0
              EE87  A8        TAY                           ---B---C A=0A X=00 Y=09 SP=01F0 ROMDIS=0
              EE88  68        PLA                           ---B---C A=0A X=00 Y=0A SP=01F0 ROMDIS=0
              EE89  AA        TAX                           ---B--ZC A=00 X=00 Y=0A SP=01F1 ROMDIS=0
              EE8A  68        PLA                           ---B--ZC A=00 X=00 Y=0A SP=01F1 ROMDIS=0
              EE8B  60        RTS                           ---B---C A=40 X=00 Y=0A SP=01F2 ROMDIS=0
              EE30  68        PLA                           ---B---C A=40 X=00 Y=0A SP=01F4 ROMDIS=0
              EE31  4C 4A 02  JMP $024A                     ---B--ZC A=00 X=00 Y=0A SP=01F5 ROMDIS=0
              024A  40        RTI                           ---B--ZC A=00 X=00 Y=0A SP=01F5 ROMDIS=0
              EB88  60        RTS                           -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
              C5EB  10 FB     BPL ReadKey                   -V----Z- A=00 X=00 Y=0A SP=01FA ROMDIS=0
ReadKey       C5E8  20 3B 02  JSR $023B                     -V----Z- A=00 X=00 Y=0A SP=01FA ROMDIS=0
              023B  4C 78 EB  JMP CheckKbd                  -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
CheckKbd      EB78  AD DF 02  LDA $02DF                     -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
              EB7B  10 0B     BPL $EB88                     -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
              EB88  60        RTS                           -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
              C5EB  10 FB     BPL ReadKey                   -V----Z- A=00 X=00 Y=0A SP=01FA ROMDIS=0
ReadKey       C5E8  20 3B 02  JSR $023B                     -V----Z- A=00 X=00 Y=0A SP=01FA ROMDIS=0
              023B  4C 78 EB  JMP CheckKbd                  -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
prb28 commented 5 years ago

Hi, I'm the coder of the vscode amiga assembly extension. I stumbled in your link to the FS-UAE issue. As you guessed there are two parts for the GDB debuging:

nekoniaow commented 5 years ago

I'm the coder of the vscode amiga assembly extension. I stumbled in your link to the FS-UAE issue. [...] I didn't use gdb as client, but only the remote protocol definition. I hope this helps, feel free, to ask any question.

Hi @prb28 ! Thanks for the notice, this is definitely helpful. A cursory look at your additions in https://github.com/emoon/fs-uae/blob/master/src/remote_debug/remote_debug.cpp makes me think your work should be fairly adaptable to Oricutron in principle. I suppose the main changes to VSCode who enable the remote debugging are those in https://github.com/prb28/vscode-amiga-assembly/blob/master/src/fsUAEDebug.ts ?

prb28 commented 5 years ago

In the vscode extension the most important files for debugging are the socket communication proxy: https://github.com/prb28/vscode-amiga-assembly/blob/master/src/gdbProxy.ts (some parsing modifications must be done for registers, breakpoints, etc.) and the vscode interface: https://github.com/prb28/vscode-amiga-assembly/blob/master/src/fsUAEDebug.ts (at least you must modify the source line to memory offset match, and certainly more things...). You will find the glue to the extension in: https://github.com/prb28/vscode-amiga-assembly/blob/master/src/debugAdapter.ts and https://github.com/prb28/vscode-amiga-assembly/blob/master/src/extension.ts.

nekoniaow commented 5 years ago

In the vscode extension the most important files for debugging are [...]

Ok, thanks again, this indeed confirms that the VS Code interface is indeed fairly isolated and very easily adaptable. Now, I must admit I would much prefer having to deal with a Visual Studio extension rather than VS Code (I try to avoid Electron apps) but the opportunity seems to good to pass. Thanks again!

prb28 commented 5 years ago

For the vscode interface there is the Language server protocol: https://microsoft.github.io/language-server-protocol/ , https://code.visualstudio.com/api/language-extensions/language-server-extension-guide. It may spare some electron development. At the time, there was already an effort to implement the gdb remote protocol by emoon so I used his code, but there are others solution that can be considered: Nodejs protocol or GDB Mi protocol.