Shop OBEX P1 Docs P2 Docs Learn Events
To ORGH or not to ORGH? - Page 3 — Parallax Forums

To ORGH or not to ORGH?

13

Comments

  • It's perfectly reasonable to say that ORGH with a value won't work in mixed Spin/PASM code. The compiler could emit a warning or error in this case. Just plain "ORGH" to say "this code should be in HUB, but I don't care where" should work.

    My main concern was avoiding the need for triple at, so if a single at gives the absolute hub address that's great. (I wish the forum code weren't so aggressive about messing with @, it makes it hard to be precise in this discussion!)
  • ElectrodudeElectrodude Posts: 1,657
    edited 2019-04-10 19:38
    Dave Hein wrote: »
    EDIT: Maybe the independent DAT section could contain global symbols that any object could directly address. That's a feature that would have been useful in Spin1.

    I like this idea, but could it be possible to label these global DAT sections (e.g. "DAT label"), so that their symbols don't pollute the global namespace? There could be global CON sections as well, which should be similarly namespaceable.
  • Cluso99Cluso99 Posts: 18,069
    edited 2019-04-10 22:27
    Chip,
    There are specific instances where you needed to know the absolute hub position of compiled code, hence the @ @ @ inclusion in bst and homespun. Sometimes this involved setting many fields with spin before using coginit, but these were not the only cases. And when it was required, there was no other way to calculate the address. There was a lot of discussion at the time and there was no other way to do it.
  • cgraceycgracey Posts: 14,152
    edited 2019-04-10 22:34
    Cluso99 wrote: »
    Chip,
    There are specific instances where you needed to know the absolute hub position of compiled code, hence the @ @ @ inclusion in bst and homespun. Sometimes this involved setting many fields with spin before using coginit, but these were not the only cases. And when it was required, there was no other way to calculate the address. There was a lot of discussion at the time and there was no other way to do it.

    It seems to me that now, with relative addressing for branches and LOC for relative-to-absolute address resolution, we only need the initial hub address to jump to. A PASM program can reference its code and data without any modification.
  • Cluso99Cluso99 Posts: 18,069
    I dont think this solves the reasons for knowing the absolute compiled hub addresses.
  • cgraceycgracey Posts: 14,152
    Cluso99 wrote: »
    I dont think this solves the reasons for knowing the absolute compiled hub addresses.

    What, for example, is needed?
  • Cluso99Cluso99 Posts: 18,069
    Sorry Chip. I cannot recall the precise circumstances as the code requiring this was a number of years ago. There was lots of discussions at the time. I was not the only one needing this and its why Brad and Michael added it to their compilers.
    I am fairly sure that LOC will not solve this problem though.
    Not everything we do on P1 or P2 fits the usual moulds ;)
  • Searching for @ @ @ (minus the spaces) discussions is really hard, because the new forum software butchered all the old posts such that the triple @ is now just @ in the old posts.
    See this example: https://forums.parallax.com/discussion/149759/operator

    It's really hard to figure out the discussion, because all the instances of triple @ or double @ are now just a single @, and so it's very difficult to even parse the discussion.

    Seriously, the forum software using the @ symbol to tag names really sucks for many reasons, but especially so because it butchered countless old posts with any discussion of the @, double @, and triple @ in them.
  • The obvious reason for code to want to get absolute hub addresses is for COG code to access data in HUB, for example something like:
        ORG 0
    entry
       ...
       loc  ptra, #@message
       call #print_string
       ...
       ORGH
    message
       byte "hello, world!", 13, 10, 0
    

    Note that the LOC is running in the COG, not HUB, so the LOC needs to use an absolute addressing form. Well, technically the compiler could cause it to get the address correct in relative mode, but it would still need to know the absolute address of "message" (because the running COG code is located at an absolute address in COG memory).

    Yes, there are alternatives (like using the ptrb value passed in at COG startup time to calculate the correct address for message). But those are more complicated and beginners are likely to trip over them. It'd be really nice if the "obvious" code above worked.
  • RaymanRayman Posts: 14,646
    Didn't Chip say that that would still work?
    I think using labels will work, right?

    I think just trying to force the data to a certain spot won't work.
    Something like this won't work if you expect it to be at $1000:
    ORGH $1000
    message
       byte "hello, world!", 13, 10, 0
    
  • evanhevanh Posts: 15,916
    edited 2019-04-11 14:58
    The LOC instruction always fills the register with an absolute address. The relative part is only in the opcode encoding. It took a while for this detail to sink in for me.

    A notable problem that confounded early efforts was all the assemblers incorrectly encoded the LOC opcode when relative encoding of addresses below $400.

    Fastspin is now fixed - https://forums.parallax.com/discussion/comment/1457051/#Comment_1457051
    Here's the updated source code snippet - https://forums.parallax.com/discussion/comment/1468883/#Comment_1468883
    Presumably the other assemblers will be fixed soon.
  • evanh, could you please post a short test program that illustrates the problem, and I'll look into it for p2asm.
  • evanhevanh Posts: 15,916
    edited 2019-04-11 21:53
    Try the one I've already posted [in the first link]. It's well tested and the actual test code is short and commented.
  • I didn't see a short program that would assemble at that link.
  • evanhevanh Posts: 15,916
    You can see the attached file right? Are you wanting smaller file size?
  • Yes, the attached file contains too much non-relevant stuff. Here's a test I did.
                       dat
    00000 000                  org     0
    00000 000 fe90002c         loc     pa, #cog1 'Relative: (address - PC - 1) << 2
    00004 001 fe9003f8         loc     pa, #hub1 'Relative: (address - PC - 1) << 2
    00008 002 fe800430         loc     pa, #hub2 'Absolute: address
    0000c 003 fe80000c         loc     pa, #\cog1 'Absolute: address
    00010 004 fe800100         loc     pa, #\hub1 'Absolute: address
    00014 005 fe800430         loc     pa, #\hub2 'Absolute: address
    00018 006 fe9000a4         loc     pa, #@cog1 'Relative: (address - PC - 1) << 2
    0001c 007 fe9003e0         loc     pa, #@hub1 'Relative: (address - PC - 1) << 2
    00020 008 fe800430         loc     pa, #@hub2 'Absolute: address
    00024 009 fe800030         loc     pa, #\@cog1 'Absolute: address
    00028 00a fe800100         loc     pa, #\@hub1 'Absolute: address
    0002c 00b fe800430         loc     pa, #\@hub2 'Absolute: address
    00030 00c 00000000 cog1    long    0
                       
    00100                      orgh    $100
    00100     00000000 hub1    long    0
                       
    00400                      orgh    $400
    00400     fe80000c         loc     pa, #cog1 'Absolute: address
    00404     fe800100         loc     pa, #hub1 'Absolute: address
    00408     fe900024         loc     pa, #hub2 'Relative: address - PC - 4
    0040c     fe80000c         loc     pa, #\cog1 'Absolute: address
    00410     fe800100         loc     pa, #\hub1 'Absolute: address
    00414     fe800430         loc     pa, #\hub2 'Absolute: address
    00418     fe800030         loc     pa, #@cog1 'Absolute: address
    0041c     fe800100         loc     pa, #@hub1 'Absolute: address
    00420     fe90000c         loc     pa, #@hub2 'Relative: address - PC - 4
    00424     fe800030         loc     pa, #\@cog1 'Absolute: address
    00428     fe800100         loc     pa, #\@hub1 'Absolute: address
    0042c     fe800430         loc     pa, #\@hub2 'Absolute: address
    00430     00000000 hub2    long    0
    
    I modified p2asm to add the comments at the end of each LOC line. LOC is encoded the same way JMP and CALLx are encoded. It looks like it doing the right thing. Of course some of the encodings aren't that useful, but that's the way the instruction is defined. It seems like "\@" should always be used in practice.
  • evanhevanh Posts: 15,916
    :( It's not that major to look at. The testing part is small and well documented. There is a real issue to fix.
  • OK, well I'm a bit dense. Can you point out on my example what needs to be fixed?
  • ersmithersmith Posts: 6,053
    edited 2019-04-12 02:06
    Dave Hein wrote: »
    Yes, the attached file contains too much non-relevant stuff. Here's a test I did.
                       dat
    00000 000                  org     0
    00000 000 fe90002c         loc     pa, #cog1 'Relative: (address - PC - 1) << 2
    00004 001 fe9003f8         loc     pa, #hub1 'Relative: (address - PC - 1) << 2
    
    It should not have the <<2.

    Consider the instruction
        loc pa, #2
    
    After this executes, pa should have the value 2, regardless of whether the loc was executing from COG or HUB RAM. But if you multiply all the relative offsets by 4 in COG mode, that becomes impossible.

    This is a case where all 3 assemblers went wrong, I think for the same reason -- we all treated LOC like JMP and friends. But the hardware does not treat the instructions the same.

    Here's a program you can use to test this:
    DAT
    	org 0
    	loc pa, #2
    	add pa, #56	' offset from pin 56
    loop
    	drvnot	pa
    	waitx	##10000000
    	jmp	#loop
    

    This should blink pin 58. When compiled with PNut v32i, p2asm 0.010, and fastspin 3.9.24 it blinks pin 61 instead. In fastspin 3.9.25-beta, with the shift removed, it's blinking pin 58 as expected.
  • evanhevanh Posts: 15,916
    The contents in PA register doesn't work out for the first two cases. The first one I think is due to difference from JMP/CALL ie: In cogram, unlike JMP/CALL, LOC needs encoded as longword scaled addressing not byte scaled.

    The second one, the encoding has never made sense. Needless to say PA content is garbage as a result. This one more likely to be used in practice.
  • OK, so the only change would be to remove the "<< 2" that used for the cog mode, correct. Has Chip looked at this, and does he agree with that?

    It seems like the relative mode is fairly useless for the LOC instruction. Should we just ignore the relative mode, and only encode absolute addresses?
  • evanhevanh Posts: 15,916
    edited 2019-04-12 05:09
    The same difference in scaling applies to absolute. It's possibly just coincidence it only affected relative.
  • rjo__rjo__ Posts: 2,114
    I understand about half of the discussion. So, well done: everyone.

    First, getting rid of the res assignments did solve my problem … So, ORGH is dead to me:)
    When I looked back at my legacy code it seems that I added "x long 1" type statements after the res assignments... which breaks the rules but didn't stop me from what I was doing:)

    I am a pretty good example of the average user, I don't want to know everything. Half the time, it changes anyway.

    I just want to know what I need to know to do what I want to do. I can look at the patterns, follow them and do not really care why they exist.

    @Chip: If you like it. Leave it alone. Let the teachers deal with it.
  • cgraceycgracey Posts: 14,152
    Dave Hein wrote: »
    OK, so the only change would be to remove the "<< 2" that used for the cog mode, correct. Has Chip looked at this, and does he agree with that?

    It seems like the relative mode is fairly useless for the LOC instruction. Should we just ignore the relative mode, and only encode absolute addresses?
    Dave Hein wrote: »
    OK, so the only change would be to remove the "<< 2" that used for the cog mode, correct. Has Chip looked at this, and does he agree with that?

    It seems like the relative mode is fairly useless for the LOC instruction. Should we just ignore the relative mode, and only encode absolute addresses?

    The relative mode is the most valuable because it enables relocatable hub code to always get addresses of its data structures. LOC in absolute mode is just a way to load a 20-bit constant (address) into PA/PB/PTRA/PTRB.
  • evanhevanh Posts: 15,916
    Ha! #hub1 isn't suposed to be relative at all. It's crossing domains so should have been encoded as an absolute. That's why that one is so busted.
  • evanhevanh Posts: 15,916
    rjo__ wrote: »
    When I looked back at my legacy code it seems that I added "x long 1" type statements after the res assignments... which breaks the rules but didn't stop me from what I was doing:)

    I am a pretty good example of the average user, I don't want to know everything. Half the time, it changes anyway.
    I think that confusion will be avoided once "objects" are in use. Then the RES definitions will always be placed at the end of each object like they are on the Prop1.
  • evanhevanh Posts: 15,916
    edited 2019-04-12 07:25
    evanh wrote: »
    Ha! #hub1 isn't suposed to be relative at all. It's crossing domains so should have been encoded as an absolute. That's why that one is so busted.
    And conversely (I think fastspin also does this):
    00400                      orgh    $400
    00400     fe80000c         loc     pa, #cog1 'Absolute: address
    00404     fe800100         loc     pa, #hub1 'Absolute: address
    
    #hub1 for this one should be relative encoding because it's hub to hub addressing.
  • evanh wrote: »
    The same difference in scaling applies to absolute. It's possibly just coincidence it only affected relative.
    Where do you see p2asm scaling the absolute address?
    cgracey wrote: »
    The relative mode is the most valuable because it enables relocatable hub code to always get addresses of its data structures. LOC in absolute mode is just a way to load a 20-bit constant (address) into PA/PB/PTRA/PTRB.
    But the relative mode is relative to the PC where the LOC instruction is executed. In order to use the relative address you would need to know the value of the PC at that time. I don't see how that is useful. Now if it was relative to a base address then it might be useful.
    evanh wrote: »
    Ha! #hub1 isn't supposed to be relative at all. It's crossing domains so should have been encoded as an absolute. That's why that one is so busted.
    The rules for hub1 demonstrate where things are broken. The value of the symbol hub1 is it's hub address since it is defined under ORGH. However, it's value is below $400, which is why relative addressing is used when assembling an instruction defined under ORG. I'm not sure how to fix this.
  • cgraceycgracey Posts: 14,152
    edited 2019-04-12 13:46
    Dave, the PC is known at runtime, so LOC can give you an absolute address when your code only knows the relative offset from the PC. By writing hub-exec code which uses relative branches and relative LOC's, you can have an entire PASM application which can sit at any byte offset in hub memory in which it fits, and it will execute without any external pointers being required. You only need to JMP to the start of the code.
Sign In or Register to comment.