@ or \ addressing - which to use?

Peter JakackiPeter Jakacki Posts: 7,868
edited May 17 in Propeller 2 Vote Up0Vote Down
I have been led to believe that the @ forces absolute addressing but in modifying code that used @ in the jmp adressing in hub rom it didn't affect anything but when I modified it in my copy in first 64k it responded. Investigating further at the actual machine code generated by PNut I found that the jump was relative $FD9x_xxxx where the lsb of 9 is the Relative addressing mode. However if I use the \ then it becomes $FD8x_xxxx plus also I can see the destination address is absolute. So what is going on? Is it supposed to be @ for relative and \ for absolute?

I have done other tests with and without etc but this is the main point in question. This is hubexec code btw.

Hubexec calling hubexec code where I have now changed it to \ to call Cluso's monitor from TAQOZ.
DEBUGGER	setint1	#0
		jmp 	#\_Start_Monitor	' \ forces absolute address '

Tachyon Forth - compact, fast, forthwright and interactive
useforthlogo-s.png
--->CLICK THE LOGO for more links<---
Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
Brisbane, Australia
«1

Comments

  • 39 Comments sorted by Date Added Votes
  • Cluso99Cluso99 Posts: 14,236
    edited May 17 Vote Up0Vote Down
    Some results from pnut's listing
    DAT
                    orgh            $1000
                    org             0                               cog
    		long	        $3d3d3d3d
                    jmp             #_hub		' 00 20 80 FD   abs hub
                    jmp             #@_hub          ' 00 20 80 FD   abs hub   <---
                    jmp             #\_hub          ' 00 20 80 FD   abs hub   <---
                    
    _cog		long	        $3d3d3d3d
                    jmp             #_cog          	' F8 FF 9F FD   rel cog
                    jmp             #@_cog          ' 10 10 80 FD   abs hub   <---
                    jmp             #\_cog          ' 04 00 80 FD   abs cog   <---
    
    
                    orgh            $2000                           hub
    _hub            long            $3d3d3d3d
                    jmp             #_hub           ' F8 FF 9F FD   rel hub
                    jmp             #@_hub          ' F4 FF 9F FD   rel hub   \ ???
                    jmp             #\_hub          ' 00 20 80 FD   abs hub   / ???
                    
    		long	        $3d3d3d3d
                    jmp             #_cog           ' 04 00 80 FD   abs cog
                    jmp             #@_cog          ' F4 EF 9F FD   rel cog   \ ???
                    jmp             #\_cog          ' 04 00 80 FD   abs cog   / ???
    

    NOTE: The #@ and #\ are reversed depending on whether the code is executing from hub or cog!!!

    pnut has a bug :(

    I hope this does not cause a ROM compile problem.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • My understanding is that @ does *not* mean anything special in jumps; what it means (in all instructions other than "rep") is to use the hub address of a label rather than the cog address. For labels that are "obviously" in hub memory (following an orgh) "@label" and "label" will mean the same thing.

    To force an absolute jump use "\" (always). Otherwise whether the jump is absolute or relative depends on whether it crosses between COG and HUB. If there's no crossing and no "\" then the jump will be relative, otherwise absolute.

    If you really want to force an absolute jump to the hub address of an instruction (even for things that will be loaded into COG memory) use "jmp #\@label".

    I think this is consistent with what Cluso saw. In the first example we're jumping from COG to HUB memory, so all the variants had to use an absolute address. In the second "jmp #_cog" is a COG to COG, so relative, but "jmp #@_cog" specifically asks for a HUB address, so it's treated as a COG/HUB crossing and comes out absolute (it'll switch to hubexec mode). In the third example "_hub" is in hub memory, so "jmp #_hub" and "jmp #@_hub" are treated the same; it's a HUB to HUB transfer so relative. Finally the label "_cog" is in COG memory so the jumps to it from HUB are absolute. However, "jmp #@_cog" comes out relative because, again, we're asking for the HUB address and so forcing it to be a HUB to HUB transfer.
  • My understanding of the @ symbol is to return the absolute hub address of COG labels only.
    So in that case the only error seems to be the second last example instruction.
                    jmp             #@_cog          ' F4 EF 9F FD   rel cog
    'should be
                    jmp             #@_cog          ' 04 00 80 FD   abs cog
    
    Melbourne, Australia
  • We have a linear address space for instructions. Why isn't the same linear address space used for data? Or is it? I thought COG addresses were 0x0 to 0x1ff, LUT addresses were 0x200-0x3ff, and hub addresses were 0x400 and up. Then why do we need something to indicate whether an address is in COG, LUT, or hub space?
  • ozpropdev wrote: »
    My understanding of the @ symbol is to return the absolute hub address of COG labels only.
    So in that case the only error seems to be the second last example instruction.
                    jmp             #@_cog          ' F4 EF 9F FD   rel cog
    'should be
                    jmp             #@_cog          ' 04 00 80 FD   abs cog
    
    No, I think it should be a relative branch, because "@_cog" is a hub address, and we're starting in hub memory. " @ " on its own doesn't mean "use absolute hub address", it just means "use hub address". If you want "use absolute hub address" you need both "\" (absolute) and " @ " (hub address). At least, that's the way I understand it and implemented it in fastspin, and it seems to match PNut. But perhaps Chip can chime in and clarify things for us.

    Eric
  • David Betz wrote: »
    We have a linear address space for instructions. Why isn't the same linear address space used for data? Or is it? I thought COG addresses were 0x0 to 0x1ff, LUT addresses were 0x200-0x3ff, and hub addresses were 0x400 and up. Then why do we need something to indicate whether an address is in COG, LUT, or hub space?

    I think it's complicated for a number of reasons:

    (1) there is HUB memory from 0x0 to 0x3ff, and so there needs to be a way to access that 1K of RAM
    (2) data access has to use different instructions depending on which memory is accessed: rdlong/wrlong for hub, rdlut/wrlut for LUT, and mov for COG

    (2) is a particular pain for compilers and interpreters, because it means we can't have generic pointers that point anywhere :( If we were starting from scratch I'd recommend changing this, but it's *way* too late for that I think :) Besides, even for instructions things get pretty complicated, as we've seen from the discussions above.
  • We are having problem with jumps and calls going to the wrong place. We need to be able to tell the compiler jump/call this routine in cog, lut or hub. Currently we cannot reliably force the jump/call :(
    The _cog and _hub labels are not really data, they are instructions located in cog and hub respectively.
    And the results are opposite depending upon whether the jump/call is currently in cog or Hub.

    IMHO this is plainly wrong and may result in our ROM containing incorrect jump/call addresses. We just don't know for sure although it's likely ok.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • @ersmith

    jmp #\@_cog 'from hub
    Got it!
    Melbourne, Australia
  • David Betz wrote: »
    We have a linear address space for instructions. Why isn't the same linear address space used for data? Or is it? I thought COG addresses were 0x0 to 0x1ff, LUT addresses were 0x200-0x3ff, and hub addresses were 0x400 and up. Then why do we need something to indicate whether an address is in COG, LUT, or hub space?
    Instructuctions can only (normally) reference cog registers because we are limited to 9 bits for both S and D operands.
    But we cannot always use absolute addresses for a few reasons.
    Not all jump/call instructions have enough bits to fully address the entire memory map.
    Hub data addresses between $00000-$00400 do exist and overlap cog and LUT space.
    We may want the code to be relocatable.
    We may want to call a routine that may reside in cog as well as Hub. Yes, I do that now with Chip's booter - I call his routines as hubexec even though he loads them into cog and LUT and runs them from there. His method is faster, but when I call them they may not exist in cog or LUT. My SD and Monitor code runs totally in hubexec mode.
    TAQOZ runs in lower Hub and cog. It is compiled for ROM but is copied down to lower Hub.

    So you see, these are real instances, not contrived examples.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Cluso99Cluso99 Posts: 14,236
    edited May 17 Vote Up0Vote Down
    ozpropdev wrote: »
    My understanding of the @ symbol is to return the absolute hub address of COG labels only.
    So in that case the only error seems to be the second last example instruction.
                    jmp             #@_cog          ' F4 EF 9F FD   rel cog
    'should be
                    jmp             #@_cog          ' 04 00 80 FD   abs cog
    
    Or it's a documentation error too.

    Currently Chip, Peter and I are using JMP/CALL #@hub to mean an address in HUB ROM. This is compiling correctly (thankfully) for the case where the jump/call is executing from cog. This is how Chip passes control to SD, TAQOZ and the Monitor.

    When this was sorted around a week ago, I converted one of my code blocks (IIRC it was SD) from # to #@. It's probably not going to matter either way, but it's not the right way.

    We will need a proper resolution and a pnut fix.

    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • David BetzDavid Betz Posts: 12,913
    edited May 17 Vote Up0Vote Down
    ersmith wrote: »
    David Betz wrote: »
    We have a linear address space for instructions. Why isn't the same linear address space used for data? Or is it? I thought COG addresses were 0x0 to 0x1ff, LUT addresses were 0x200-0x3ff, and hub addresses were 0x400 and up. Then why do we need something to indicate whether an address is in COG, LUT, or hub space?

    I think it's complicated for a number of reasons:

    (1) there is HUB memory from 0x0 to 0x3ff, and so there needs to be a way to access that 1K of RAM
    (2) data access has to use different instructions depending on which memory is accessed: rdlong/wrlong for hub, rdlut/wrlut for LUT, and mov for COG

    (2) is a particular pain for compilers and interpreters, because it means we can't have generic pointers that point anywhere :( If we were starting from scratch I'd recommend changing this, but it's *way* too late for that I think :) Besides, even for instructions things get pretty complicated, as we've seen from the discussions above.
    Ugh. Do you mean that the first location in hub memory is 0x400 if we're executing code from it and 0x0 if we're accessing it as data. That seems like a big mistake.

    Edit: I guess that isn't true. Phew! We just can't execute code from the first 0x400 bytes of hub memory. That seems fine.

  • ersmithersmith Posts: 2,451
    edited May 17 Vote Up0Vote Down
    Cluso99 wrote: »
    We are having problem with jumps and calls going to the wrong place. We need to be able to tell the compiler jump/call this routine in cog, lut or hub. Currently we cannot reliably force the jump/call :(
    I believe you can reliably force an absolute jump/call as follows:
        jmp #\@_cog ' jump to the hub address of _cog
        jmp #\_cog  ' jump to the cog/lut address of _cog (if it is in cog/lut memory)
        jmp #\_hub  ' jump to the hub address of _hub (if it is in hub memory; in that case same as jmp #\@_hub)
    
    What seems to be missing is a way to force a relative jump and to give an error if it cannot be relative.
    The _cog and _hub labels are not really data, they are instructions located in cog and hub respectively.
    For the assembler there's no difference between data labels and instruction labels -- they're just labels. My understanding (based on the docs and on reverse engineering PNut) is that labels have two values: their "default value" (if no " @ " is used in front of them) and their "hub value" (if " @ " is used in front of them). After .orgh these two values are the same. After .org they are different, and the "default value" becomes the COG/LUT address based on the .org. " @ " applies to the label, not the instruction, and forces the hub value to be used. That is, "jmp #@_cog" just means "jmp to the hub address of the label _cog", and whether that jump is relative or absolute is determined by the crossing rules. Similarly, "mov x, ##@_cog" will place the hub address of _cog into x.

    An example would be:
    DAT
        orgh $400
        org $80
    x
        jmp #x   ' same as jmp #$80: relative
        jmp #\x  ' same as jmp #\$80: forced absolute
        jmp #\@x ' same as jmp #\$400: forced absolute
        jmp #@x  ' same as jmp #$400:  absolute due to crossing
    
        long x   ' same as long $80
        long @x  ' same as long $400
    

    PNut and p2asm both handle this the same. fastspin chokes on the #\@, I need to fix that (using #\(@x) does work).
  • I'm afraid I still don't understand the difference between a hub and a COG address. I understand that COG/LUT overlap the first 0x400 bytes of hub memory. Is that the only issue? Otherwise, the value of the address determines where it is in the memory map I think. Or are you distinguishing between the address in hub memory where a COG image resides before COGINIT vs. where it is in the COG?
  • potatoheadpotatohead Posts: 9,566
    edited May 17 Vote Up0Vote Down
    What seems to be missing is a way to force a relative jump and to give an error if it cannot be relative.

    I'm having trouble locating the discussion, but I believe this is correct. Chip said something along the lines of, "Relative jumps COG to HUB, HUB to COG are a bad idea" and discouraged them. Nobody talked about relocatable code that does this back then. Here we are with the ROM, and it's a valid case.

    What was discussed was the fact that the instructions permit it, but as a general programming practice, the assembler wouldn't actually do that. Not making a statement on that, just recalling the relevant discussion we had at the time.

    Questions:

    Is that a general case we need to fix in Pnut? I'm asking, because Chip's reason was the high difficulty and potential for error present when doing this kind of thing.

    (Since we are likely to publish this ROM code as part of the chip docs, we should fix this, or at least document how to make it explicit.)

    At the time we had the discussion, we did not have the robust debug capability we do now. Does that debug cover doing this well enough?

    Do not taunt Happy Fun Ball! @opengeekorg ---> Be Excellent To One Another SKYPE = acuity_doug
    Parallax colors simplified: https://forums.parallax.com/discussion/123709/commented-graphics-demo-spin<br>
  • David Betz wrote: »
    I'm afraid I still don't understand the difference between a hub and a COG address. I understand that COG/LUT overlap the first 0x400 bytes of hub memory. Is that the only issue? Otherwise, the value of the address determines where it is in the memory map I think. Or are you distinguishing between the address in hub memory where a COG image resides before COGINIT vs. where it is in the COG?

    I guess it depends on what you're talking about, but I think for jump purposes addresses $0-$3ff are treated as cog/lut memory and $400 up are treated as hub memory. That means you cannot do an absolute jump to a hub address below $400. It is (theoretically) possible to do relative jumps to such addresses, but in practice the assembler may give errors because it thinks you'll be crossing between the hub and cog domains, and relative branches are not supposed to do that.
  • David BetzDavid Betz Posts: 12,913
    edited May 17 Vote Up0Vote Down
    ersmith wrote: »
    David Betz wrote: »
    I'm afraid I still don't understand the difference between a hub and a COG address. I understand that COG/LUT overlap the first 0x400 bytes of hub memory. Is that the only issue? Otherwise, the value of the address determines where it is in the memory map I think. Or are you distinguishing between the address in hub memory where a COG image resides before COGINIT vs. where it is in the COG?

    I guess it depends on what you're talking about, but I think for jump purposes addresses $0-$3ff are treated as cog/lut memory and $400 up are treated as hub memory. That means you cannot do an absolute jump to a hub address below $400. It is (theoretically) possible to do relative jumps to such addresses, but in practice the assembler may give errors because it thinks you'll be crossing between the hub and cog domains, and relative branches are not supposed to do that.
    So this issue of absolute COG/LUT vs. hub addressing really just amounts to how to handle the first 0x400 bytes? Or do we also have to deal with the two low-order bits being missing from COG/LUT addresses?

  • David Betz wrote: »
    So this issue of absolute COG/LUT vs. hub addressing really just amounts to how to handle the first 0x400 bytes? Or do we also have to deal with the two low-order bits being missing from COG/LUT addresses?

    There's also the complication that every label has two values, its "default" value (which may be in COG memory) and its hub value (which definitely is in hub memory). The hub value is accessed via " @ ". The documentation is a little unclear on this whole concept, I'm afraid, and it's easy to think that " @ " signals an absolute jump (it doesn't, only "\" signals an absolute jump.
  • ersmith wrote: »
    David Betz wrote: »
    So this issue of absolute COG/LUT vs. hub addressing really just amounts to how to handle the first 0x400 bytes? Or do we also have to deal with the two low-order bits being missing from COG/LUT addresses?

    There's also the complication that every label has two values, its "default" value (which may be in COG memory) and its hub value (which definitely is in hub memory). The hub value is accessed via " @ ". The documentation is a little unclear on this whole concept, I'm afraid, and it's easy to think that " @ " signals an absolute jump (it doesn't, only "\" signals an absolute jump.
    When would the COG and hub address of a variable be different? Are we talking about the two low-order bits?

  • When would the COG and hub address of a variable be different? Are we talking about the two low-order bits?

    I posted an example earlier in the thread, but another simple one:
        orgh $400
        org   0
    entry
        jmp #entry
        long entry  ' will be 0
        long @entry ' will be $400
    
    Here the default (cog) address of entry is 0 (set by org) and the hub address is $400. "@entry" gives the hub address. "entry" gives just the default address, which in this case is a cog address.

    If you take away the "org 0" then both addresses will be the same, that is " @entry " and "entry" will both have the value $400.
  • It's actually nothing to do with the lower $400 of Hub.

    It's to do with how to force the compiler to do what the programmer wants, and for this method to be consistent.

    We have code in the Hub ROM area commencing at $FC000. This is the code executed when the final silicon P2 boots. It's in hubexec mode. It copies code from, for ease let's say from $FC000 into cog and from FC800 into lut, and then jumps to let's say cog $000. So the same code can be present in both cog and Hub. Similarly LUT and Hub but let's forget that.
    So that code has a cog address and a hub address.
    If I want my program to jump to that code, I need to tell the compiler which address to use, cog or Hub. Currently I have to know if my code (the code doing the jumping) is currently running in cog or hub, because the method of forcing the compiler to do the jump to cog or hub is reversed depending on whether my jumping code is running from cog or hub. That's a bug because the instruction format should be the same!! See my code results posted above. They are taken from the real pnut output!!
    Now, the code that Chip executes in cog also resides in Hub. And when I need to call it, it's no longer available in cog. But it is still in Hub, and it is compatible with hubexec operation (not all code can run in hubexec because some instructions don't work in Hub). So I have to force the compiler to jump/call a routine using its hub address.
    The alternative is for each of us to have identical routines in hub which is a waste (and we no longer have the space either).

    Eric, sorry you are incorrect. See my top post where I show what pnut produces.
    Again, it's not the compiler that has issues with Hub execution addresses below $400 (which I think is actually $400 << 2 = Hub $1000), but rather the P2 silicon PC (program counter) is 20 bits and addresses in the bottom 2KB are interpreted as cog and the next 2KB as lut. When in cog/lut I believe its the bottom 2bits that get discarded as cog and lut are only addressed as longs. Hub is addressed in bytes, and I believe can. execute from odd addresses. Certainly rdlong can fetch from a non-long aligned address.

    Potatohead, the ROM of a few versions back has already been published for testing purposes. It may be included with the latest FPGA code - I got mine directly from Chip and it's in the zip file.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Cluso99 wrote: »
    Eric, sorry you are incorrect. See my top post where I show what pnut produces.
    I'm sorry, I think we're talking past each other somehow. Your top post seems consistent with what I would expect, namely " @label " is always treated as a hub address, and whether or not a jump is absolute is an orthogonal question. The jump is absolute either if (a) an explicit "\" is given before it, or (b) the code has to jump from cog to hub or vice-versa.

    If code in hub jumps to a label with " @ " in front of it (and no "\") it will always use a relative jump, since it's hub to hub. If code in cog jumps to a label with " @ " in front of it (and no "\") then it will always use an absolute jump, since it's cog to hub.

    So if you really want an absolute jump to a hub address use both "\" and " @ ", namely:
       jmp #\@_cog
    

    If I'm mistaken, could you explain what I have wrong? I do want to get this right for fastspin.

    Whether this is the way the assembler should work is another question, of course. I'm just describing how (I think) it actually does work.

  • Eric,
    Sorry I wasn't aware until you said today that the #\@label was legitimate. It never crossed my mind.
    So what I am saying is pnut is not consistent within the rules that we thought we were using.
    With that further explanation, I will need to look again. That's not going to happen for another 18 hrs at least.
    Perhaps in the meantime you might test these out with pnut for us?
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • OT
    What was interesting while Peter and I were discussing this problem, we both used our own tools (TAQOZ and the Monitor) to "patch" the ROM.
    Not bad eh!!
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • ersmith wrote: »
    When would the COG and hub address of a variable be different? Are we talking about the two low-order bits?

    I posted an example earlier in the thread, but another simple one:
        orgh $400
        org   0
    entry
        jmp #entry
        long entry  ' will be 0
        long @entry ' will be $400
    
    Here the default (cog) address of entry is 0 (set by org) and the hub address is $400. "@entry" gives the hub address. "entry" gives just the default address, which in this case is a cog address.

    If you take away the "org 0" then both addresses will be the same, that is " @entry " and "entry" will both have the value $400.
    So the difference between COG and hub address is due to the code being assembled to reside in hub memory (it's hub address) but it is then copied to COG memory for execution and hence also has a COG address?

  • Dave HeinDave Hein Posts: 5,641
    edited May 17 Vote Up0Vote Down
    All code resides in hub RAM, so everything has a hub address. If an ORG directive is used the code will also have a cog address starting with the address specified by the ORG directive. Symbols that have a cog attribute will result in the cog address if it is not preceded by an @. If an @ is used, then the result is the hub address.

    For symbols that do not have a cog attribute it doesn't matter if the @ symbol is used or not. The result is always a hub address.

    Here's the listing output from p2asm when assembling a short snippet of code. The first column shows the hub address, and the second column shows the cog address. Note that the code after the ORGH does not have a cog address. Jumps from cog to cog and hub to hub use relative addresses unless the \ character is present, which forces an absolute jump. Jumps between cog and hub always use an absolute address.
    00400                  orgh $400
    00400 000              org   0
    00400 000          entry
    00400 000 fd9ffffc     jmp #entry
    00404 001 fd800000     jmp #\entry
    00408 002 fd800400     jmp #@entry
    0040c 003 fd800400     jmp #\@entry
    00410 004 fd800428     jmp #entry1
    00414 005 fd800428     jmp #\entry1
    00418 006 fd800428     jmp #@entry1
    0041c 007 fd800428     jmp #\@entry1
    00420 008 00000000     long entry
    00424 009 00000400     long @entry
                       
    00428                  orgh
    00428              entry1
    00428     fd800000     jmp #entry
    0042c     fd800000     jmp #\entry
    00430     fd9fffcc     jmp #@entry
    00434     fd800400     jmp #\@entry
    00438     fd9fffec     jmp #entry1
    0043c     fd800428     jmp #\entry1
    00440     fd9fffe4     jmp #@entry1
    00444     fd800428     jmp #\@entry1
    00448     00000428     long entry1
    0044c     00000428     long @entry1
    
  • David BetzDavid Betz Posts: 12,913
    edited May 17 Vote Up0Vote Down
    Dave Hein wrote: »
    All code resides in hub RAM, so everything has a hub address. If an ORG directive is used the code will also have a cog address starting with the address specified by the ORG directive. Symbols that have a cog attribute will result in the cog address if it is not preceded by an @. If an @ is used, then the result is the hub address.

    For symbols that do not have a cog attribute it doesn't matter if the @ symbol is used or not. The result is always a hub address.

    Here's the listing output from p2asm when assembling a short snippet of code. The first column shows the hub address, and the second column shows the cog address. Note that the code after the ORGH does not have a cog address. Jumps from cog to cog and hub to hub use relative addresses unless the \ character is present, which forces an absolute jump. Jumps between cog and hub always use an absolute address.
                       dat
    00400                  orgh $400
    00400 000              org   0
    00400 000          entry
    00400 000 fd9ffffc     jmp #entry
    00404 001 fd800000     jmp #\entry
    00408 002 fd800418     jmp #@entry1
    0040c 003 fd800418     jmp #\@entry1
    00410 004 00000000     long entry
    00414 005 00000400     long @entry
                       
    00418                  orgh
    00418              entry1
    00418     fd800000     jmp #entry
    0041c     fd800000     jmp #\entry
    00420     fd9ffff4     jmp #@entry1
    00424     fd800418     jmp #\@entry1
    00428     00000418     long entry1
    0042c     00000418     long @entry1
    
    That makes sense. Thanks. I guess complexity comes if you want the code to work either at its COG or its hub address. Then relative addressing helps resolve the problem.

  • I'm sure there will be uses for creating code that can be executed in either cog or hub, but I think most of the time we will want to dedicate the code to either cog or hub execution exclusively. Also, instructions that use the data streamer cannot be executed from the hub since hubexec requires the data streamer as well.

    A nice feature of relative addressing is that it allows for position independent code. A snippet of hub code could execute equally starting at location $400 or $FFF0. For a while I supported a position independent code (PIC) mode in p2gcc. The jumps could be done from anywhere in memory. However, I did have to adjust the data addresses to match where the data is located in memory.
  • Cluso99 wrote: »
    Sorry I wasn't aware until you said today that the #\@label was legitimate. It never crossed my mind.
    So what I am saying is pnut is not consistent within the rules that we thought we were using.
    With that further explanation, I will need to look again. That's not going to happen for another 18 hrs at least.
    Perhaps in the meantime you might test these out with pnut for us?

    I must agree that the documentation is confusing. I was lucky that I already had " @ " in my mind as an operator that acts on labels (like "-") rather than an instruction modifier (like "#" or "\"). So my mental picture agreed with Chip's.

    Below is a slightly modified version of your original post. As you can see the " #\@ " form always gives a jump to abs hub. I've checked and p2asm and PNut both produce the same result. fastspin kind of does as well, if you give it the -c option to just extract the DAT. Otherwise fastspin wants to compile a Spin method and optimizes everything away when it doesn't find one :(. Again, something I will need to fix. This has been very enlightening...
    DAT
                    orgh            $1000
                    org             0                              
    		long	        $3d3d3d3d
                    jmp             #_hub		' 00 20 80 FD   abs hub
                    jmp             #@_hub          ' 00 20 80 FD   abs hub
                    jmp             #\_hub          ' 00 20 80 FD   abs hub
    		jmp		#\@_hub		' 00 20 80 FD   abs hub
                    
    _cog		long	        $3d3d3d3d
                    jmp             #_cog          	' F8 FF 9F FD   rel cog
                    jmp             #@_cog          ' 14 10 80 FD   abs hub
                    jmp             #\_cog          ' 05 00 80 FD   abs cog
    		jmp		#\@_cog		' 14 10 80 FD   abs hub
    
    
                    orgh            $2000                          
    _hub            long            $3d3d3d3d
                    jmp             #_hub           ' F8 FF 9F FD   rel hub
                    jmp             #@_hub          ' F4 FF 9F FD   rel hub
                    jmp             #\_hub          ' 00 20 80 FD   abs hub
    		jmp		#\@_hub		' 00 20 80 FD   abs hub
                    
    		long	        $3d3d3d3d
                    jmp             #_cog           ' 05 00 80 FD   abs cog
                    jmp             #@_cog          ' F4 EF 9F FD   rel cog
                    jmp             #\_cog          ' 05 00 80 FD   abs cog
    		jmp		#\@_cog		' 14 10 80 FD   abs hub
    

    Thanks,
    Eric
  • cgraceycgracey Posts: 10,477
    edited May 17 Vote Up0Vote Down
    Cluso sent me a set of branch cases to which I've added the "#\@address' case:
    DAT
    	orgh	$01000
    	org	0	'cog code
    
    cog	jmp	#cog	'$FD9FFFFC	cog to cog, relative
    	jmp	#\cog	'$FD800000	cog to cog, force absolute
    	jmp	#@cog	'$FD801000	cog to hub, always absolute
    	jmp	#\@cog	'$FD801000	cog to hub, always absolute
    
    	jmp	#hub	'$FD802000	cog to hub, always absolute
    	jmp	#\hub	'$FD802000	cog to hub, always absolute
    	jmp	#@hub	'$FD802000	cog to hub, always absolute
    	jmp	#\@hub	'$FD802000	cog to hub, always absolute
    
    	orgh	$02000	'hub code
    
    hub	jmp	#cog	'$FD800000	hub to cog, always absolute
    	jmp	#\cog	'$FD800000	hub to cog, always absolute
    	jmp	#@cog	'$FD9FEFF4	hub to hub, relative
    	jmp	#\@cog	'$FD801000	hub to hub, force absolute
    
    	jmp	#hub	'$FD9FFFEC	hub to hub, relative
    	jmp	#\hub	'$FD802000	hub to hub, force absolute
    	jmp	#@hub	'$FD9FFFE4	hub to hub, relative
    	jmp	#\@hub	'$FD802000	hub to hub, force absolute
    


    Keep in mind that "@address" always returns the hub address of the label, even if the label also represents a cog address. The implication of using "@address" in branches is that the assembler sees you branching to a hub address.

    I might be missing something, but it seems that the assembler is working correctly. This needs more documentation, though.
  • Thanks guys.
    It has taken a while to get to the bottom of this.

    I am happy that what I am using in my code is working as desired, but it is more by luck than good management.

    Now I can clean it up to ensure I use what I want the compiler to do. I will use the #\@label or #@label when I want to jump/call hubexec code. Currently I have no need to jump/call cog or lut code, but that will come later for sure.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
Sign In or Register to comment.