6502bench icon indicating copy to clipboard operation
6502bench copied to clipboard

Provide way to isolate regions

Open BacchusFLT opened this issue 2 years ago • 9 comments

The region function works really well, but once defined and you realise that you need to change the end of it, you can't. Is there any reason it's not possible to update the selected range here? I tend to do a preliminary selection, but the program requires that you make a final selection once you define it.

BacchusFLT avatar Jan 30 '23 22:01 BacchusFLT

In the docs, under Editors > Create/Edit Address Region:

Resize If you select multiple lines, and the first line is an address region start directive, you will be able to resize that region to the selection. By definition, the updated region will have a fixed end point.

So just select the new region you want, making sure that the .addrs line is at the top, right click and Create/Edit Address Region. The top option in the dialog that opens should be "Resize", showing the new end offset and length.

If you don't get the .addrs line selected, it thinks you're trying to create a sub-region, and gets a little bent out of shape if the end straddles an existing end.

FWIW, the docs also note:

There is no affordance for moving the start offset of a region. You must create a new region and then delete the old one.

So you can grow/shrink them but you can't move them.

fadden avatar Jan 30 '23 23:01 fadden

Gotcha!

Would say there could be a value in allowing the user to type in the end value. Right click on the .addrs and there have an input field for the end address.

Question was of course triggered from an actual need, and I solved it by deleting and recreating.

BacchusFLT avatar Jan 31 '23 10:01 BacchusFLT

One other aspect of regions (should possibly have it's own item);

On the c64, the disk drive is a totally separate device with it's own CPU, ram, Kernal and the lot. You normally populate the disk drive by having the code in the computer and then write it to the drive ram, over the serial bus.

Using the region function, I can set that chunk of ram as something that is to be executed on another address, but I guess there is no (current) way to avoid that addresses it references are turned into labels in the general program.

Could I pass the suggestion that it would be possible for a region to be more isolated from the general program, having local labels?

In the below, $1c00 is an address in the VIA timer chip of the drive, and not the ram as RAM address $1c00 in the computer. I have refined it as part of a region, so it's in one location of the computer ram, but as you can see, the labels at assuming it's on $0300, so that part works fine.

L035B           ldx   #$f5            ;2
                txs                   ;2
                lda   #$c8            ;2
                jsr   L033B           ;6
                ldx   #$24            ;2
L0365           ldy   L1C00           ;4
                tya                   ;2
                and   #$fc            ;2
                sta   $00             ;3
                dey                   ;2
                tya                   ;2
                and   #$03            ;2
                ora   $00             ;3
                sta   L1C00           ;4
                lda   #$0a            ;2
                jsr   L033B           ;6
                dex                   ;2
                bne   L0365           ;2+
                lda   #$0f            ;2
                jsr   L033B           ;6

BacchusFLT avatar Jan 31 '23 11:01 BacchusFLT

Would say there could be a value in allowing the user to type in the end value.

I think that could feel natural if we did text editing within the list view UI element (i.e. the field becomes editable, instead of popping open a dialog box). Might be possible.

Could I pass the suggestion that it would be possible for a region to be more isolated from the general program, having local labels?

This is a significant concern for 65816 code, mostly because of the sheer scope of some of the projects. In that case the project would likely be handled by generating multiple source files and linking the outputs together. That's probably not what you want here.

This situation essentially has two different things at the same address (not really, but the assembler doesn't know that). What makes this unusual is that one of the things is inside the program and one of them isn't. So you'd want some of the code to use the label and other parts of the code to use a project/platform symbol, and we'd need a way to specify which parts of the code use each.

In assembler source you'd have an equate for $1c00 and use that symbol on the operands. Right now in SourceGen you'd need to do something similar, defining a project/platform symbol and setting it explicitly on the operands that reference the "external" address.

The address region stuff provides a measure of label scoping, giving priority to things that are "closer", but it doesn't let you say that parts of the code are completely inaccessible to other parts.

FWIW you can have local labels (prefix with '@' by default), but that mechanism is intended for loops and local branches. We'd need a more general label-scoping mechanism, possibly just a checkbox on the address dialog that says, "nothing in this region can access labels elsewhere, and vice-versa". An exception could be made for labels marked "global, marked for export" so they're not totally isolated.

fadden avatar Jan 31 '23 21:01 fadden

Spot on analysis.

In my own case I could rip out the drive code segment and handle that separately, and in this part of the project just make the entire section as junk I guess. But that is not the optimal general approach. A tickbox for making it unavailable, as you said might still be best if it's doable. Possibly a reference to the disk drive, like the main references the main system would be a similar approach.

Den tis 31 jan. 2023 22:04Andy McFadden @.***> skrev:

Would say there could be a value in allowing the user to type in the end value.

I think that could feel natural if we did text editing within the list view UI element (i.e. the field becomes editable, instead of popping open a dialog box). Might be possible.

Could I pass the suggestion that it would be possible for a region to be more isolated from the general program, having local labels?

This is a significant concern for 65816 code, mostly because of the sheer scope of some of the projects. In that case the project would likely be handled by generating multiple source files and linking the outputs together. That's probably not what you want here.

This situation essentially has two different things at the same address (not really, but the assembler doesn't know that). What makes this unusual is that one of the things is inside the program and one of them isn't. So you'd want some of the code to use the label and other parts of the code to use a project/platform symbol, and we'd need a way to specify which parts of the code use each.

In assembler source you'd have an equate for $1c00 and use that symbol on the operands. Right now in SourceGen you'd need to do something similar, defining a project/platform symbol and setting it explicitly on the operands that reference the "external" address.

The address region stuff provides a measure of label scoping, giving priority to things that are "closer", but it doesn't let you say that parts of the code are completely inaccessible to other parts.

FWIW you can have local labels (prefix with '@' by default), but that mechanism is intended for loops and local branches. We'd need a more general label-scoping mechanism, possibly just a checkbox on the address dialog that says, "nothing in this region can access labels elsewhere, and vice-versa". An exception could be made for labels marked "global, marked for export" so they're not totally isolated.

— Reply to this email directly, view it on GitHub https://github.com/fadden/6502bench/issues/139#issuecomment-1411068637, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGZWZSTQT55OIWIF7GT7IZDWVF463ANCNFSM6AAAAAAULWKL4Q . You are receiving this because you authored the thread.Message ID: @.***>

BacchusFLT avatar Feb 01 '23 00:02 BacchusFLT

Plan:

  • Add an "isolated region" checkbox to the address region editor.
  • Add matching flag to the internal data structures. Save/load from project file.
  • Modify AddressMap.AddressToOffset() so that it halts when it encounters the flag. It won't descend into a child that has the flag, and won't traverse upward or laterally if the current node has the flag. This should allow a region to be isolated but still have sub-regions that can see each other.
  • Add appropriate test cases (unit tests in AddressMap and asm regression test).
  • Document feature as being useful for cases where the code/data is transferred to a region with an independent address space.

Net effect should be to prevent the label finder from seeing the addresses at all, so it will treat address references as external if they're not satisfied locally.

Care should be taken NOT to isolate address region pre-labels, since those are only defined for use by code that does the relocation.

I think that's all we need... reasonably straightforward and low-risk.

EDIT: semi-permeable regions may be useful. Issue #147 has multi-bank code that overlaps; the switching segment's addresses are called locally, but the addresses referenced in the implementation are in the other bank. This could also work for NES Metroid, which has multiple banks at $8000 that are accessed from common code in bank $c000, but the first segment is at $8000 but doesn't support the "API". The first segment still needs to call out to $c000, but shouldn't be used to resolve call-backs.

fadden avatar Feb 02 '23 00:02 fadden

Added "isolated region" feature to "TO DO" wiki.

fadden avatar Feb 02 '23 01:02 fadden

Following our decent discussion and me continuing working on the cartridge project a bit more, I concluded that local labels are great things for making labels not leak out of a particular context and then keep then from colliding with the outside. But the other way around - labels from the outside, leaking in and polluting the disassembly - is likely a bigger problem here. Local labels won't help in that scenario. I take it the solution you are looking at will block leaking in both directions?

My current usecase have a number of routines copied to low mem, and run there. Especially the ones copied to zeropage get totally incomprehensible due to collision with Zeropage usage in other parts of the program. But this is still the same memory space with a lateral difference.

The other part is the number of disk drive routines sent to the drive and executed there. They are contextually different - run in a separate machine (as already mentioned, the disk drive has it's own CPU, timers, RAM and Kernal). So $0400 in the drive is not the same as the $0400 in the computer.

I'm sure it adds a lot of complexlity, but here it could be relevant to open up the thought

  • there could be a need to do a local exception to the global symbol file definitions (c64-kernal is only relevant for the computer part - not the drive part, and here the kernal definitions are also different for the different drive types) - defining a region as destined to be run in a different entity, is clearly indicating a need for separation.
  • outlier: different contexts could need be joined (different segments attributed to being drive code could share data), so all the stuff tagged as say 1541 drive, could share labels

BacchusFLT avatar Jul 12 '23 20:07 BacchusFLT

The current proposal for the "isolated region" flag is bi-directional. The address-to-offset converter would not search into or out of an isolated region when mapping an address reference to a place in the code.

Defining multiple scopes for symbols can become awkward when generating the assembly output, because all output is written to a single file. Even if the assembler is capable of managing multiple label scopes, I think it would be confusing to have a single file with multiple definitions of a global equate or label. The platform symbols (from .sym65 files) can be overridden with project symbols, but they always have global scope.

The simpler model would be to generate multiple source files, where each one has a separate set of global definitions. That's probably how it was structured in the original source. That would likely be a lot of work on the SourceGen side though.

fadden avatar Jul 12 '23 22:07 fadden

Now available in pre-release build: https://github.com/fadden/6502bench/releases/tag/v1.9.0-dev1

The address region edit dialog has a pair of checkboxes in the "advanced" section that allow blocking of address resolution inbound and outbound, respectively.

fadden avatar May 23 '24 17:05 fadden