SamCoVT / TaliForth2

A Subroutine Threaded Code (STC) ANSI-like Forth for the 65c02
Other
28 stars 4 forks source link

Simple debugger for c65 #85

Closed patricksurry closed 2 months ago

patricksurry commented 2 months ago

Here's a very simple debugger for c65. See c65/README.md for an overview. Seems to work well for starting Tali interactively with ctrl-C to get back to debugger and explore. I found a variant of linenoise which gives nice command-line editing (and cross-session history) and runs on win native, wsl plus os x. It uses a small set of ansi escape sequences for color-coding but this also seems portable 🤞.

My C is extremely rusty so no doubt some bugs are lurking. See what you think.

SamCoVT commented 2 months ago

This looks very good and is exactly (more than, really) what I had in mind. Works well on Linux, so I think that covers all of the platforms we currently support. I'll test it a bit more thoroughly this weekend and will probably merge it then unless you want me to hold off.

With this as an alternative to py65mon, the only parts of Tali2 that need python are forth_to_ophisbin.py (probably should rename this - it's referenced in Makefile and docs) and the tests.

patricksurry commented 2 months ago

yup, fine to merge.

i 've only done ad hoc testing while writing it so no doubt rough edges remain!

could probably add some simple unit tests piping commands from file and checking output/crash but i haven't done anything there yet.

On Tue, May 21, 2024 at 2:42 PM SamCoVT @.***> wrote:

This looks very good and is exactly (more than, really) what I had in mind. Works well on Linux, so I think that covers all of the platforms we currently support. I'll test it a bit more thoroughly this weekend and will probably merge it then unless you want me to hold off.

With this as an alternative to py65mon, the only parts of Tali2 that need python are forth_to_ophisbin.py (probably should rename this - it's referenced in Makefile and docs) and the tests.

— Reply to this email directly, view it on GitHub https://github.com/SamCoVT/TaliForth2/pull/85#issuecomment-2123230537, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABA5MKXQ7HNDCY4BVGPSIUDZDOIRBAVCNFSM6AAAAABIARROQKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRTGIZTANJTG4 . You are receiving this because you authored the thread.Message ID: @.***>

SamCoVT commented 2 months ago

I quickly took the docs/py65mon-labelmap.txt file from 64tass and transmogrified it into a sequence of label commands and loaded them in, and it made it much nicer to do debugging. There were a few oddities, like lda 0,x became lda ram_start, x, but I can deal with that by perhaps not loading in any values less than 6. I also didn't load in any values that weren't in hex (they don't have a $ in front of the value in the labelmap) because those were mostly constants and not addresses.

If I end up using it a lot, I will probably add a feature to load the 64tass labelmap in directly or write a tool to turn it into label statements. 64tass also has some support for limiting which labels are put in the labelmap. That's a future thing, though. It's quite usable as it is.

patricksurry commented 2 months ago

There should already be a super-hacky version of that via the -l option - see the README debugger walkthru here https://github.com/SamCoVT/TaliForth2/pull/85/files#diff-5f6bedf630e7d9b0380b71a0023566e8fbff870ff2d8a1c4e2e336f8c951c0fbR102 and implementation here https://github.com/SamCoVT/TaliForth2/pull/85/files#diff-4802b73bb4d43c37948ee44066f90638f62ec547f2210013a53f98c99cb72fcbR760

Sounds like we went down similar path tho - it only loads labels that start with $ and exactly four hex digits. I think 64tass can also output vice-style labels which might be a better input source since you can exclude numeric constants and the like.

It does make debugging much nicer tho, esp in conjunction with 'call

patricksurry commented 2 months ago

I'm also finding the memory r/w breakpoints v useful - i added sort of as an afterthought because it was easy, but nice to break when a specific memory location gets read/written, and great for watching underflow read/write or rom writes

SamCoVT commented 2 months ago

I totally missed the -l option. Thanks for pointing that out. It's very usable for now. Does a Makefile target of cdebug with c65/c65 -r taliforth-py65mon.bin -g -l docs/py65mon-labelmap.txt as the action make sense?

Once this is committed, does it make sense to add a platform file for c65, rather than using the py65mon target? I don't want to get rid of the py65mon target, as there are some users that may be using it. The c65 target would add support for the block file and make csim (or make cdebug) would add the command line for that as well, so that you drop into an environment with block support.

Once that exists, I think a reasonable next step would be to move the block-ramdrive-init code out of Tali and provide it as forth code in the examples folder instead (with instructions in the source file). It's still useful for those who want to play with a ramdrive block device (on real hardware, perhaps), but we can use c65 for the tutorial and simply mention the ramdrive version as an alternative. I'm hoping to have more time this summer to work on the documentation, and we can add that to the list.

SamCoVT commented 2 months ago

ooh... I also just found ~. That is simple, but very shiny. I was going to ask if you could break on a range of memory accesses... then I looked, and of course you can. I especially like how you can choose what kind of access. I also found unlabel and was able to unlabel 0 for less silly stack manipulation disassembly.

I'll play a little more with it this weekend, but good job. It's very easy to use.

patricksurry commented 2 months ago

sounds like a good idea to add csim/cdebug targets and a c65 platform file. it would be great if the c65 platform could simply include and extend the py65 one somehow? both to reduce duplication and make sure they don't diverge other than block support

SamCoVT commented 2 months ago

I think you've already done a lot of that work by separating out the I/O into "simulator.asm" for your minimal platform.

One thing that is missing (that might be helpful here, and I think it was brought up by a user some time ago) is that the forth_words and user_words are not tied to the platform, so it's not possible to have versions of those for one platform without them being used for other platforms as well.

Another feature that might be useful would be a TURNKEY word that is run right at the end of COLD and could be overridden in assembly (or Forth by redefining it). That would allow things like installing the block vectors without having to run a forth word interactively to do it.

An alternative to TURNKEY for installing the block vectors automatically would be use conditional compilation to either use the existing routine (that prints an error) or the user provided routines (if they are provided). I like the idea of it working "out of the box" without having to run a word to set the vectors, and others could use it in their platform file by naming their block I/O routines with the special names (like kernel_block_read and kernel_block_write?)

The only downside I can see is that they are a little more difficult to write as they will need to access the Forth stack. The other kernel routines just use A to pass the data. The c65 platform file could serve as an example of how to do it.

All of this can be considered as a separate issue/PR and shouldn't affect this PR.