fadden / 6502bench

A workbench for developing 6502 code
https://6502bench.com/
Apache License 2.0
170 stars 32 forks source link

More hotkeys #11

Closed oziphantom closed 6 years ago

oziphantom commented 6 years ago

; = add comment L = add label P = add param label D = data W = word C = code Something = Line comment

fadden commented 6 years ago

Adding comments / labels and editing operands can be done with double-clicking, but I could see the usefulness of keyboard shortcuts if you want to keep your hands on the keyboard. The only one I've really missed is "add long comment", since there's no way to click for that.

Are "D=data" / "C=code" for applying hints? I was thinking of making that a two-key combo, like Ctrl-H Ctrl-C, since they're (hopefully) rarely needed. What would "W=word" do? (Note you can bulk-apply data formatting by ctrl+clicking or ctrl+shift+clicking, where the last click is a double-click on the operand to open the Edit Data dialog.)

The default ListView wants to go searching for an entry if you start typing non-control characters, though I've suppressed that behavior. I'm still leaning toward making the shortcuts all Ctrl+whatever though.

I do like ';' for "add comment" -- feels natural.

oziphantom commented 6 years ago

W sets it to a 16 bit data statement so $00 $80 Select them and say Word .word $8000 When using the programs, reversing code is a really long and arduous task, so you want to not have to open a menu as much as possible it just makes the process take 4x longer.

fadden commented 6 years ago

Gotcha. There are various situations to consider for 'W':

  1. both items are single-byte, default format
  2. both items are single-byte, but one or both have some other format
  3. the selected item is formatted as a 16-bit value, but doesn't match exactly what 'W' would make it (maybe it's big-endian, maybe it's little-endian but with a symbol or decimal formatting)
  4. the selected item is already 16-bit / little-endian numeric / hex

Seems like (1) and (2) should just make it 16-bit / little-endian numeric / hex, regardless of previous format choices. (4) could flip it back to single-byte default format, making 'W' act as a toggle. Not sure what (3) should do... could change it to little-endian-numeric / hex, could flip it back to bytes.

Any strong feelings on 'W' vs. Ctrl-W? At some point the settings screen might get one of those massive keyboard shortcut mapping screens, but I'm secretly hoping to avoid that. (Huh, guess that's not a secret anymore.)

Update: item (3) could actually rotate. Select two bytes, Ctrl+W to make them 16-bit little-endian numeric. Ctrl+W again makes them 16-bit little-endian addresses. Ctrl+W a third time returns them to default-formatted bytes. I had originally planned to do something like this for operand formats, so you could rotate lda #$41 through hex / decimal / ascii / binary by banging on a key repeatedly, but dropped it from 1.0 because the creeping featurism was hitting extreme levels.

oziphantom commented 6 years ago

This won't scale very well, 65816 will just explode this into a MESS. Make setting the Data type, Byte, Word, LoByte, HiByte 1 step. then Making it a "lookup" be another step. Then we only have 1 "make it a label and add it to the system for me please" function. That then only has to deal with a 16bit or 24bit param.

When you get to looking at 65816 ( I've made a supeRegenerator which handles SNES ROMs - trust me there are a lot of things you need to do when you start looking at 8MB of stuff ;) )you then have this nightmare Bank byte Hi byte Lo byte

Lo byte Hi byte Bank byte

Bank byte Lo byte Hi byte

Hi byte Bank byte Lo byte

Lo byte Bank byte Hi byte

Bank byte LoWord

HiWord LoByte

HiWord LoWord ( where the 'hibyte' is shared in both

then you have all of the above, but in data tables where you have N of each in memory. So make it so you set each type to be what they are, then "make lookup" ;) saves at lot of case statements ;)

Then you have all of the above where the bank is set as the Databank ;) Then you have all of the above where the Direct Page has been moved to ;)

42Bastian commented 6 years ago

Are "D=data" / "C=code" for applying hints? I was thinking of making that a two-key combo, like Ctrl-H Ctrl-C, since they're (hopefully) rarely needed. What would "W=word" do? (Note you can bulk-apply data formatting by ctrl+clicking or ctrl+shift+clicking, where the last click is a double-click on the operand to open the Edit Data dialog.)

Ctrl-C is no good idea ;-)

oziphantom commented 6 years ago

Ctrl+C is copy. And unless you want to go Amiga Spec with "insert" being copy, probably best to leave it for copying selected code. Shift + C maybe?

fadden commented 6 years ago

It would be Ctrl+H Ctrl+C (or Ctrl+H C). So hitting Ctrl+H sets a flag that modifies how the next key hit is handled. I'll admit to being a little wary of this approach since I haven't used it before and I'm not sure what hidden "gotchas" there might be, but Visual Studio and Excel both use it (e.g. Ctrl+R Ctrl+R for a refactor-rename in VS, Alt+I R to insert a row in Excel.)

Re: 65816 code, I wrote commercial software for the Apple IIgs once upon a time, so I'm familiar with 24/32-bit pointer issues. (OTOH, Apple IIgs software came on 800K floppies, so it's rare to see a single binary larger than a couple hundred K.) On the IIgs it's very unusual to see pointers in anything but little-endian byte order, which is why the data format dialog offers big-endian for 16-bit data items but not 24-bit data items. I don't know how the SNES compares. (I wrote some compression code for the SNES version of the XBAND modem once upon a time, but didn't learn much about the SNES beyond how to push code to the PsyQ.)

Keyboard shortcuts should make it easy to do the things that you do all the time. Formatting large tables of pointers or strings in arbitrary ways is okay to do with a dialog. (Click first item, shift+doubleclick operand field of last item in list, click desired format, click OK... and there's standard Windows Alt-shortcuts for most things.) If you're frequently formatting items as 16-bit words, and sometimes you want hex data and sometimes you want addresses, you can select the bytes and then Ctrl+W for hex, or Ctrl+W Ctrl+W for address, or hit Ctrl+W one more time if you change your mind. You're correct that it doesn't scale -- rotating through all possible 16-bit formats, including big-endian order and binary and the rest, would just be annoying.

Another question is whether it should grab the following byte automatically if only one byte is selected.

oziphantom commented 6 years ago

re SNES. you know who when we first got C++ and people were "you can overload the operators and make them do other things" and not thinking about how dumb that would be in the long term did it... some people on the SNES looked at every feature of the 65816 like that.. And then there are the people who really didn't understand the 65816 and make the worst code imaginable.

Another fun thing they like to do is put variables after the jsr and then patch the stack (I've seen this on NES as well, see Metroid for example) so you end up with

01/F35D 20 99 11                                     jsr callLocalOtherBankAsLong 
01/F360                                              .long DMAtoFroKepScnUntilDone
01/F363 20 99 11    b01F363                          jsr callLocalOtherBankAsLong 
01/F366                                              .long p048946

I can't find an example as I changed my SNES Regerator format and broke some things ;) but you also get things like

jsr DecompressData
.long $048534      ;source
.word $8000,$1000  ;size, VRAM address
.byte $83          ;transfer mode
lda #$00

can your analysis tool work out that the function DecompressData fiddles with the Stack to change the return address for these cases?

2MB is typical SNES ROM size, 4MB common, 6MB is rare. 8MB is possible but I think only "hacks" are that big. To which banking is critical, as you then only have to show and edit 32K or 64K. I even make it so you enable labels on per bank basis. This way something random trash data in bank 7 doesn't put a whole bunch of fake variables in bank 2. It takes quite a while to scan all the banks for labels, and that is just dump looking not code simulation like yours, I even bother to make the code multitreaded and show progress bars, still takes a while.

If you select a byte and say "word" or "long" then it should grab the next 1,2 bytes as needed. I even added a Shift Mode to mine so it would auto insert 2 WORDs, or 2 LONGs quickly. But then I also added a custom struct mode that let me add things to a text file and select the format from a right click menu, as once you get something like Decompress Data it tends to be used a lot through the code. So I even then added a "auto apply this format after all calls to XXXXX" function.

fadden commented 6 years ago

The stuff that comes after the JSR needs to be hinted as "inline data". There's no easy way for SourceGen to do this automatically, but you can define an extension script that does it. (In fact, that's pretty much all extension scripts are good for at this point.) For example, Apple II ProDOS 8 does this:

JSR $bf00
.dd1 [function]
.dd2 [address]

If you look at the ProDOS 8 extension script, you can see that it identifies the call, formats the function as a symbol (if the function is listed in the .sym65 file) or number, and formats the address as an address (which is a numeric reference that gets an auto-label if nothing is defined). I show this briefly near the end of the youtube demo video.

Scripts can be defined for a specific project. So you'd add the addresses of callLocalOtherBankAsLong and DecompressData to the script, add any symbolic constants to a .sym65, and have it all done automatically. It means writing C# code to do the work, rather than describing it in some sort of generic way, but it gives you the flexibility to deal with cases where the inline data doesn't have a fixed format or length.

Right now extension scripts just get called for JSR/JSL. There's another one in there that converts IIgs toolbox calls from LDX #xxxx / JSL Toolbox to LDX #symbol / JSL toolbox... it's not limited to inline data. You can reformat the entire file if you want.

fadden commented 6 years ago

Current state of things...

Ctrl+L -> Edit Label Ctrl+; -> Edit Comment Ctrl+M -> Edit Long (Multi-line) Comment Ctrl+N -> Edit Note Ctrl+H, Ctrl+C -> set code hint Ctrl+H, Ctrl+D -> set data hint Ctrl+H, Ctrl+I -> set inline data hint Ctrl+H, Ctrl-R -> remove hints Ctrl+D -> toggle "analyze uncategorized data" Ctrl+B -> Toggle Single-Byte Format Del -> delete Note or Long Comment

(most of that got added after alpha3 was released)

I stole Ctrl+W back from File>Close to use it as a Format As Word, though I still haven't decided what that looks like.

42Bastian commented 6 years ago

Seems quite intuitive.

Maybe use Ctrl-O as "Edit operand" instead of open. Open is less often used then changing the operand.

Now add Ctrl-X Ctrl-S for saving and I am happy ;-)

fadden commented 6 years ago

Ugh... emacs users.

:wq

fadden commented 6 years ago

Opened #29 for the lingering question about Ctrl+W. The rest is done.