GeorgRottensteiner / C64Studio

C64Studio is a .NET based IDE specializing in game development for the C64 in assembler and BASIC
Other
251 stars 38 forks source link

Indirect addressing of labels? #119

Closed truebluepl closed 3 months ago

truebluepl commented 3 months ago

Let's suppose we have 3 routines:

Routine1
 lda #0
 rts
Routine2
 lda #1
 rts
Routine3
 lda #2 
 rts

And table with pointers to these routines:

RoutinesPtrs
!word Routine1
!word Routine2
!word Routine3

Now I have another structure, let's call it "sequence":

Sequence
!byte 0 ; index to the Routine1 inside RoutinePtrs
!byte 10,11,12 ; some arguments
!byte 4 ; index to the Routine3 inside RoutinePtrs
!byte 20,21,22
!byte 2 ; index to the Routine2 inside RoutinePtrs
!byte 30,31,32

Would be nice to have the following functionality:

Sequence
!byte RoutinesPtrs->Routine1 ; index of label Routine1 (not the pointer to the Routine1) starting from RoutinesPtrs
!byte 10,11,12
!byte RoutinesPtrs->Routine3 ; index of label Routine3 starting from RoutinesPtrs
!byte 20,21,22
!byte RoutinesPtrs->Routine2 ; index of label Routine2 starting from RoutinesPtrs
!byte 30,31,32
GeorgRottensteiner commented 3 months ago

Interesting, but very specialized. Also, very brittle :)

For one this only works if !word has only single label entries, expressions wouldn't make sense: !word Routine2 + 5

What is supposed to happen when I do this?

RoutinesPtrs !byte Routine1 !byte Routine2 !byte Routine1

Which index will RoutinesPtrs->Routine1 get?

Syntax wise I'd probably go for RoutinesPtrs.Routine1 (because it wouldn't introduce a new -> operator) I could however make it clearer by not using !word but introducing a new pseudo op; e.g. !jumptable.

Any !jumptable entry would add a local label to the current global zone/label. This would even allow having other values in between. In the following example the offsets would result in PseudoPtrs.Routine1 = 0, PseudoPtrs.Routine2 = 6, PseudoPtrs.Routine3 = 8.

PseudoPtrs !jumptable Routine1 !byte 1,2,3,4 !jumptable Routine2 !jumptable Routine3

truebluepl commented 3 months ago

Interesting, but very specialized. Also, very brittle :)

For one this only works if !word has only single label entries, expressions wouldn't make sense: !word Routine2 + 5

What is supposed to happen when I do this?

RoutinesPtrs !byte Routine1 !byte Routine2 !byte Routine1

Which index will RoutinesPtrs->Routine1 get?

I think the last one should be returned:)

Syntax wise I'd probably go for RoutinesPtrs.Routine1 (because it wouldn't introduce a new -> operator) I could however make it clearer by not using !word but introducing a new pseudo op; e.g. !jumptable.

Any !jumptable entry would add a local label to the current global zone/label. This would even allow having other values in between. In the following example the offsets would result in PseudoPtrs.Routine1 = 0, PseudoPtrs.Routine2 = 6, PseudoPtrs.Routine3 = 8.

PseudoPtrs !jumptable Routine1 !byte 1,2,3,4 !jumptable Routine2 !jumptable Routine3

It would be nice, but if I understood correctly it needs the second table should be created (with pseudopointers), right?

GeorgRottensteiner commented 3 months ago

Not sure I understand what you intend to say with the second sentence. Of course you need to have your routines set up, just like in your example before. The full usage would look like this:

;actual routines
Routine1
 lda #0
 rts
Routine2
 lda #1
 rts
Routine3
 lda #2 
 rts

;jump table (with optional extra data)
PseudoPtrs         ;<= this global label starts a new zone, !jumptable references the last global label above)
!jumptable Routine1
!byte 1,2,3,4
!jumptable Routine2
!jumptable Routine3

Sequence
!byte RoutinesPtrs.Routine1  ;= 0
!byte 10,11,12
!byte RoutinesPtrs.Routine3 ;= 8
!byte 20,21,22
!byte RoutinesPtrs.Routine2 ;= 6
!byte 30,31,32

So you could easily have several jump tables:

PseudoPtrs1
!jumptable Routine1
!byte 1,2,3,4
!jumptable Routine2
!jumptable Routine3

PseudoPtrs2
!jumptable Routine1
!byte 1,2,3,4
!jumptable Routine2
!jumptable Routine3

;use with PseudoPtrs1.Routine1, PseudoPtrs1.Routine2, PseudoPtrs1.Routine3
;and PseudoPtrs2.Routine1, PseudoPtrs2.Routine2, PseudoPtrs3.Routine3
truebluepl commented 3 months ago

Ok, I though I need two tables - original with pointers (RoutinesPtrs) and the second one (PseudoPtrs).

So !jumptable pseudooperator fulfills two tasks:

  1. Is just !word operator
  2. I can use syntax with dot to get the index of the routine/label inside this table.

Am I right now?:)

GeorgRottensteiner commented 3 months ago

Yeah, I think that's the idea. I'll see to it!

GeorgRottensteiner commented 3 months ago

Took me longer than it should have, damn late evaluation. Is this what you expected?

image

truebluepl commented 3 months ago

Georg, yes, this is it:) Is the order important? I mean, OFFSET_DATA could be placed before JUMP_LIST?

GeorgRottensteiner commented 3 months ago

OFFSETDATA can be placed before as well, that's what took the longer part :)

Updated with latest commit, new WIP version is at https://www.georg-rottensteiner.de/webmisc/C64StudioRelease.zip

GeorgRottensteiner commented 3 months ago

Sorry, the feature you wanted does work, however I worked over the idle task management. This currently breaks the debugging, which results in a hang. I'll upload a fix asap!

Edit: De-Warning. My settings file was messed up and any time "Debug Memory" ought to be shown it got stuck in the DockPanelSuite library. Completely unrelated to this case. You can go ahead!

truebluepl commented 3 months ago

Thanks, Georg,

Hmm... !jumplist pseudooperator works (like !word pseudo), but when I call label I get error message: Cannot evaluate expression RoutinesPtrs.SetTexture

RoutinesPtrs is defined as:

RoutinesPtrs
!jumplist SetTexture
...

and sequence

Sequence
!byte RoutinesPtrs.SetTexture
GeorgRottensteiner commented 3 months ago

Weird. I have several examples with a few combinations. Can you reduce your issue to a short snippet and post here?

truebluepl commented 3 months ago

Ok, I know what is the problem.

RoutinesPtrs
label1
!jumplist Routine1
label2
!jumplist Routine2

Additional labels inside JUMPLIST cannot be used, propably the reason is they change reference. I don't need these labels, so without them works ok:)

GeorgRottensteiner commented 3 months ago

Phew :) Yeah, I need to stress that in the docs, the very last previous global label is used as reference. In your case you end up with label1.Routine1 and label2.Routine2, in that particular example both being zero :)

truebluepl commented 3 months ago

Thank you again, Georg:)