Shop OBEX P1 Docs P2 Docs Learn Events
flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler - Page 24 — Parallax Forums

flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler

12122242627115

Comments

  • RaymanRayman Posts: 13,767
    Ok, it's definitely working better! There is only one obvious flaw that I see right away...
    The bottom of the screen is not being erased correctly, it's a bit off...
    The routine that does that is called "Fillbottom".
    Changing the loc to mov fixes it:
    DAT   'Fillbottom             
    FillBottom  'RJA:  just the bottom now that floorcasting is working 
                    loc     ptrb,#OffscreenBufferAddress 'image buffer
                    mov     ptrb,##OffscreenBufferAddress 
                    add     ptrb,##200*320
    
  • RaymanRayman Posts: 13,767
    I suppose using LOC to load a constant is a non-standard usage. I was a bit surprised that that worked actually...
    There is something about R=1 making it add in PC. Maybe that is what's wrong? The address is off, but not by much.

    I suppose it could be that this one is correct and all the other loc fed address are wrong... I doubt that though..
  • Cluso99Cluso99 Posts: 18,066
    edited 2019-09-16 22:46
    Eric,
    Can FASTSPIN perform conditional calculations?

    Example
    CON
    XTALV = 20_000_000 'for P2EVAL
    XTAL2 = 12_000_000 'for P2D2
    
    CLOCKFREQ = 300_000_000 'desired clock frequency
    
    'to calculate the crystal parameters...
    IF CLOCKFREQ > 200_000_000
        XDIVP=1
    ELSE
        XDIVP=2
    
    XMULV = CLOCKFREQ / XDIVP / XTALV / 5
    XMUL2 = CLOCKFREQ / XDIVP / XTAL2 / 3
    
  • Rayman wrote: »
    I suppose using LOC to load a constant is a non-standard usage. I was a bit surprised that that worked actually...
    There is something about R=1 making it add in PC. Maybe that is what's wrong? The address is off, but not by much.

    I suppose it could be that this one is correct and all the other loc fed address are wrong... I doubt that though..

    Using "loc" to load constants should work, although you do have to be careful I think about things in COG memory; using the \ operator to force an absolute rather than relative operation is probably a good idea. I'll try to figure out what's going on.
  • Cluso99 wrote: »
    Eric,
    Can FASTSPIN perform conditional calculations?

    Example
    CON
    XTALV = 20_000_000 'for P2EVAL
    XTAL2 = 12_000_000 'for P2D2
    
    CLOCKFREQ = 300_000_000 'desired clock frequency
    
    'to calculate the crystal parameters...
    IF CLOCKFREQ > 200_000_000
        XDIVP=1
    ELSE
        XDIVP=2
    
    XMULV = CLOCKFREQ / XDIVP / XTALV / 5
    XMUL2 = CLOCKFREQ / XDIVP / XTAL2 / 3
    

    You'll have to use the ?: conditional compilation operator (which I think Chip will also support):
      XDIVP = (CLOCKFREQ > 200_000_000) ? 1 : 2
    
  • RaymanRayman Posts: 13,767
    edited 2019-09-17 01:17
    Your suggestion seems to work:
    DAT   'Fillbottom             
    FillBottom  'RJA:  just the bottom now that floorcasting is working 
                    loc     ptrb,#\OffscreenBufferAddress 'image buffer
    

    Adding the "\" seems to fix the problem. I didn't even know that was an option...

    Still, it's very strange, given that OffscreenBufferAddress is a constant, defined in a CON section...
  • ersmithersmith Posts: 5,898
    edited 2019-09-17 01:30
    Rayman wrote: »
    Your suggestion seems to work:
    DAT   'Fillbottom             
    FillBottom  'RJA:  just the bottom now that floorcasting is working 
                    loc     ptrb,#\OffscreenBufferAddress 'image buffer
    

    Adding the "\" seems to fix the problem. I didn't even know that was an option...

    Still, it's very strange, given that OffscreenBufferAddress is a constant, defined in a CON section...

    The loc instruction calculates a relative address by default, regardless of whether the address is a constant or a label. The problem fastspin is having is that it doesn't know the address of the Spin object when it's first assembling it. For normal jmp and loc it's able to work around this if both the current label and the label being branched to are in the same object -- in that case the difference (used for the relative addressing) doesn't depend on the final location. For a constant though this fails :(. I'm still trying to figure out how to handle that case.

    Adding a "\" is probably a good idea for constants anyway, because you don't really want the loc to be relocatable in that case (if you move the instruction the constant calculated would change).

    Personally I would prefer that absolute addresses be the default and relative addresses be explicitly requested either by an instruction variant or flag of some kind. Chip preferred it this way, so I've followed his lead.

    Edit: there's a common confusion about what "\" and "@" mean. "\" means "use absolute addressing mode, not relative". "@" means "use the hub address of the label, even if the code is normally loaded into COG or LUT". They're independent ideas, but easy to confuse.
  • RaymanRayman Posts: 13,767
    edited 2019-09-17 10:21
    Ok, I think adding the "\" is not a problem. Actually, if I were doing it over again, I'd probably just use MOV. Or, maybe not as LOC saves one instruction...

    Anyway, the original code had OffscreenBufferAddress as an ORGH set value, not as a constant in a CON section.
    So, the use of LOC seemed to make more sense in that case.
    Actually, I think this was always a constant...

    This code only has 2 hard coded addresses for buffers. So, it shouldn't be too hard to make the change.

    I guess the real question is if, with this change of adding "\", the code will still work, whether in COG, LUT, or HUBEXEC.
  • Cluso99Cluso99 Posts: 18,066
    Nice one! That'll do it :smiley:
  • evanhevanh Posts: 15,091
    edited 2019-09-17 02:27
    Rayman wrote: »
    I guess the real question is if, with this change of adding "\", the code will still work, whether in COG, LUT, or HUBEXEC.
    Yes it'll work as expected. As Eric indicated, adding the \ makes it encode the constant exactly as defined.

    The only difference with cog addresses is, being a data reference, you will be defining such a constant as longword scale addressing rather than byte scale addressing. But that's up to you to get right when entering the revised constant.

    If it's a code reference the rules are different. Everything is byte scale addressing then. EDIT: I've not quite got my head around this part, because there is a conflict here with $400 as first hubexec.

  • Cluso99Cluso99 Posts: 18,066
    ersmith wrote: »
    Cluso99 wrote: »
    Eric,
    Can FASTSPIN perform conditional calculations?

    Example
    CON
    XTALV = 20_000_000 'for P2EVAL
    XTAL2 = 12_000_000 'for P2D2
    
    CLOCKFREQ = 300_000_000 'desired clock frequency
    
    'to calculate the crystal parameters...
    IF CLOCKFREQ > 200_000_000
        XDIVP=1
    ELSE
        XDIVP=2
    
    XMULV = CLOCKFREQ / XDIVP / XTALV / 5
    XMUL2 = CLOCKFREQ / XDIVP / XTAL2 / 3
    

    You'll have to use the ?: conditional compilation operator (which I think Chip will also support):
      XDIVP = (CLOCKFREQ > 200_000_000) ? 1 : 2
    
    Working nicely thanks Eric :smiley::smiley::smiley:

    BTW its
    XDIVP = (CLOCKFREQ > 200_000_000) ? 2 : 1

  • evanhevanh Posts: 15,091
    Yep, Pnut supports doing that with constants.

    Cluso,
    Eric had the correct 1 : 2 (true : false) order. The /1 should be used for high sysclock frequencies.

  • evanhevanh Posts: 15,091
    200 MHz is also too high, the PLL peters out below 400 MHz when running hot. 100 MHz is the recommended threshold for enthusiastic use of /2.
  • Cluso99Cluso99 Posts: 18,066
    evanh wrote: »
    Yep, Pnut supports doing that with constants.

    Cluso,
    Eric had the correct 1 : 2 (true : false) order. The /1 should be used for high sysclock frequencies.

    of course - more coffee ;)
  • Cluso99Cluso99 Posts: 18,066
    Loadp2

    I have a problem loading code into the P2EVAL when specifying the com port
    >loadp2 prog.binary -p5 -b115200 -t
    If I leave the com port off it works just fine, and yes it is com 5
    >loadp2 prog.binary -b115200 -t

    Is this a known problem?
  • evanhevanh Posts: 15,091
    Maybe "-p com5". Not sure, on Linux it's a path string so starts with -p /dev/...
  • Cluso99 wrote: »
    Loadp2

    I have a problem loading code into the P2EVAL when specifying the com port
    >loadp2 prog.binary -p5 -b115200 -t
    If I leave the com port off it works just fine, and yes it is com 5
    >loadp2 prog.binary -b115200 -t

    Is this a known problem?

    Did you try -pCOM5? You could also try picking the port from the menu in spin2gui and see if that works -- it should.
  • Cluso99Cluso99 Posts: 18,066
    -pcom5 did the trick thanks :)

    Is there a reason fastspin seems to strip leading underscores from labels?
    eg _clkfreq
  • Cluso99 wrote: »
    -pcom5 did the trick thanks :)

    Is there a reason fastspin seems to strip leading underscores from labels?
    eg _clkfreq

    Could you give an example? I'm not aware of any cases where fastspin modifies user labels. There are some cases where there are internal aliases (e.g. clkfreq and _clkfreq might be defined to be the same thing). Are you running into one of those?
  • Cluso99Cluso99 Posts: 18,066
    Yes, _clkfreq and _clkmode so I wondered if the underscore was stripped. Perhaps it was just due to those internal aliases. I'll change them in my code.
  • Cluso99Cluso99 Posts: 18,066
    Eric or Chip,
    I accidentally left the "@" off my rep instruction which didn't work as I expected. While looking for my silly mistake I found the following unusual behaviour...

    What are the requirements for the REP instruction?

    I am presuming...
    If the @label is used, it's a trick in the rep instruction to force a relative displacement.
    If #nnn is used then it's a count of the number of instructions in the loop.
    If its just a label (register) then rep will get the instruction count from the register contents.

    This is not what I expected...
    00118 046 04 C8 07 F6 |               mov       lmm_c,            #4 
    0011c 047 02 C4 07 F6 |               mov       lmm_p,            #2
    00120 048             | '              rep       lmm_p,            lmm_c        
    00120 048 E4 97 D0 FC |               rep       .repx,            lmm_c        
    00124 049 61 11 64 FC |               wrlong    z1,               PTRA++       
    00128 04a 61 13 64 FC |               wrlong    z2,               PTRA++       
    0012c 04b             | .repx
    0012c 04b 61 15 64 FC |               wrlong    z3,               PTRA++       
    00130 04c 61 17 64 FC |               wrlong    z4,               PTRA++       
    00134 04d 61 19 64 FC |               wrlong    z5,               PTRA++       
    00138 04e 61 1B 64 FC |               wrlong    z6,               PTRA++       
    0013c 04f 61 1D 64 FC |               wrlong    z7,               PTRA++       
    00140 050             | 
    00140 050 F8 C1 03 F6 |               mov       lmm_x,            PTRA
    00144 051 28 CB AF FD |               call      #_hubHex8
    
    0000401C
    04000: 11 11 11 11  22 22 22 22  33 33 33 33  44 44 44 44   '....""""3333DDDD'
    04010: 55 55 55 55  66 66 66 66  77 77 77 77  FF FF FF FF   'UUUUffffwwww....'
    04020: FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF   '................'
    04030: FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF   '................'
    *
    
    Decoding the instruction bits I get a register for D as $04B which has contents in the listing of $16 1564 FC --> $FC641514
    So I would expect that the rep instruction would repeat a lot of instructions but it doesn't doesn't perform any repeat at all and just falls thru.
    Am I missing something or is this actually a silicon bug???


    As expected...
    00118 046 04 C8 07 F6 |               mov       lmm_c,            #4 
    0011c 047 02 C4 07 F6 |               mov       lmm_p,            #2
    00120 048 E4 C5 D3 FC |               rep       lmm_p,            lmm_c        
    00124 049             | '              rep       .repx,            lmm_c        
    00124 049 61 11 64 FC |               wrlong    z1,               PTRA++       
    00128 04a 61 13 64 FC |               wrlong    z2,               PTRA++       
    0012c 04b             | .repx
    0012c 04b 61 15 64 FC |               wrlong    z3,               PTRA++       
    00130 04c 61 17 64 FC |               wrlong    z4,               PTRA++       
    00134 04d 61 19 64 FC |               wrlong    z5,               PTRA++       
    00138 04e 61 1B 64 FC |               wrlong    z6,               PTRA++       
    0013c 04f 61 1D 64 FC |               wrlong    z7,               PTRA++       
    00140 050             | 
    00140 050 F8 C1 03 F6 |               mov       lmm_x,            PTRA
    00144 051 28 CB AF FD |               call      #_hubHex8
    
    00004034
    04000: 11 11 11 11  22 22 22 22  11 11 11 11  22 22 22 22   '....""""....""""'
    04010: 11 11 11 11  22 22 22 22  11 11 11 11  22 22 22 22   '....""""....""""'
    04020: 33 33 33 33  44 44 44 44  55 55 55 55  66 66 66 66   '3333DDDDUUUUffff'
    04030: 77 77 77 77  FF FF FF FF  FF FF FF FF  FF FF FF FF   'wwww............'
    *
    

    And as expected...
    00118 046 04 C8 07 F6 |               mov       lmm_c,            #4 
    0011c 047 02 C4 07 F6 |               mov       lmm_p,            #2
    00120 048             | '              rep       lmm_p,            lmm_c        
    00120 048 E4 05 D8 FC |               rep       @.repx,            lmm_c        
    00124 049 61 11 64 FC |               wrlong    z1,               PTRA++       
    00128 04a 61 13 64 FC |               wrlong    z2,               PTRA++       
    0012c 04b             | .repx
    0012c 04b 61 15 64 FC |               wrlong    z3,               PTRA++       
    00130 04c 61 17 64 FC |               wrlong    z4,               PTRA++       
    00134 04d 61 19 64 FC |               wrlong    z5,               PTRA++       
    00138 04e 61 1B 64 FC |               wrlong    z6,               PTRA++       
    0013c 04f 61 1D 64 FC |               wrlong    z7,               PTRA++       
    00140 050             | 
    00140 050 F8 C1 03 F6 |               mov       lmm_x,            PTRA
    00144 051 28 CB AF FD |               call      #_hubHex8
    
    00004034
    04000: 11 11 11 11  22 22 22 22  11 11 11 11  22 22 22 22   '....""""....""""'
    04010: 11 11 11 11  22 22 22 22  11 11 11 11  22 22 22 22   '....""""....""""'
    04020: 33 33 33 33  44 44 44 44  55 55 55 55  66 66 66 66   '3333DDDDUUUUffff'
    04030: 77 77 77 77  FF FF FF FF  FF FF FF FF  FF FF FF FF   'wwww............'
    *
    
  • Cluso99 wrote: »
    If the @label is used, it's a trick in the rep instruction to force a relative displacement.
    If #nnn is used then it's a count of the number of instructions in the loop.
    If its just a label (register) then rep will get the instruction count from the register contents.
    I believe that is correct.
    This is not what I expected...
    00118 046 04 C8 07 F6 |               mov       lmm_c,            #4 
    0011c 047 02 C4 07 F6 |               mov       lmm_p,            #2
    00120 048             | '              rep       lmm_p,            lmm_c        
    00120 048 E4 97 D0 FC |               rep       .repx,            lmm_c        
    00124 049 61 11 64 FC |               wrlong    z1,               PTRA++       
    00128 04a 61 13 64 FC |               wrlong    z2,               PTRA++       
    0012c 04b             | .repx
    0012c 04b 61 15 64 FC |               wrlong    z3,               PTRA++       
    00130 04c 61 17 64 FC |               wrlong    z4,               PTRA++       
    00134 04d 61 19 64 FC |               wrlong    z5,               PTRA++       
    00138 04e 61 1B 64 FC |               wrlong    z6,               PTRA++       
    0013c 04f 61 1D 64 FC |               wrlong    z7,               PTRA++       
    00140 050             | 
    00140 050 F8 C1 03 F6 |               mov       lmm_x,            PTRA
    00144 051 28 CB AF FD |               call      #_hubHex8
    
    Decoding the instruction bits I get a register for D as $04B which has contents in the listing of $16 1564 FC --> $FC641514
    So I would expect that the rep instruction would repeat a lot of instructions but it doesn't doesn't perform any repeat at all and just falls thru.
    Am I missing something or is this actually a silicon bug???
    If it tries to repeat a whole bunch of instructions (which I think is indeed what it will do) then it'll run into the "call #_hubHex8" instruction at $051. If my memory is correct, call is like any other branch and will cancel the REP. I think that's what you're seeing.

  • Cluso99Cluso99 Posts: 18,066
    edited 2019-09-18 11:56
    ersmith wrote: »
    Cluso99 wrote: »
    If the @label is used, it's a trick in the rep instruction to force a relative displacement.
    If #nnn is used then it's a count of the number of instructions in the loop.
    If its just a label (register) then rep will get the instruction count from the register contents.
    I believe that is correct.
    This is not what I expected...
    00118 046 04 C8 07 F6 |               mov       lmm_c,            #4 
    0011c 047 02 C4 07 F6 |               mov       lmm_p,            #2
    00120 048             | '              rep       lmm_p,            lmm_c        
    00120 048 E4 97 D0 FC |               rep       .repx,            lmm_c        
    00124 049 61 11 64 FC |               wrlong    z1,               PTRA++       
    00128 04a 61 13 64 FC |               wrlong    z2,               PTRA++       
    0012c 04b             | .repx
    0012c 04b 61 15 64 FC |               wrlong    z3,               PTRA++       
    00130 04c 61 17 64 FC |               wrlong    z4,               PTRA++       
    00134 04d 61 19 64 FC |               wrlong    z5,               PTRA++       
    00138 04e 61 1B 64 FC |               wrlong    z6,               PTRA++       
    0013c 04f 61 1D 64 FC |               wrlong    z7,               PTRA++       
    00140 050             | 
    00140 050 F8 C1 03 F6 |               mov       lmm_x,            PTRA
    00144 051 28 CB AF FD |               call      #_hubHex8
    
    Decoding the instruction bits I get a register for D as $04B which has contents in the listing of $16 1564 FC --> $FC641514
    So I would expect that the rep instruction would repeat a lot of instructions but it doesn't doesn't perform any repeat at all and just falls thru.
    Am I missing something or is this actually a silicon bug???
    If it tries to repeat a whole bunch of instructions (which I think is indeed what it will do) then it'll run into the "call #_hubHex8" instruction at $051. If my memory is correct, call is like any other branch and will cancel the REP. I think that's what you're seeing.

    Thanks. I hadn't thought of running down the first loop and quitting. I'll need to try some variations to prove that.
  • evanhevanh Posts: 15,091
    Eric is exactly right. CALLs are a branch, and any branch cancels the REP.
  • RaymanRayman Posts: 13,767
    edited 2019-09-18 17:03
    Ok, Spin2 with big ASM seems to work OK now when it's all in one file...
    But, something is wrong when graphics cog is moved into it's own file and treated like an object.
    In this case, the address for embedded file labels are off (by about 1kB, in this case).

    I have some bmp data like this:
    DAT' Graphics Resources bitmapBitmap
    
    '
    BmpAddressBackground        
            file    "bgr_combopal2.bmp"   '640 x 100, 8pbb-lut  '65,080 bytes, 64,000 for data, $438 for other
    

    Interestingly, this doesn't seem to happen for the display driver, that also has embedded bmp data.
    Maybe because it doesn't have any hubexec code?
  • RaymanRayman Posts: 13,767
    FYI... That object is trying to get the address of the bitmap like this:
    'Copy from Graphics resource to offscreen buffer
                    loc     ptra,#\BmpAddressBackground  'hub location of background image
    
  • evanhevanh Posts: 15,091
    There is header/palette data at the start of bitmap pictures. The image data is a few hundred bytes in.

    Another possibility is the load address is below $400. If that's the case then you may need to use the @ to force byte scale addressing to suite hubRAM. eg: LOC ptra,#@BmpAddressBackground
  • Just an aside, it really seems like LOC isn't being used for its intended purpose and it'll drive the compiler and assembler writers insane?
  • evanhevanh Posts: 15,091
    Encoding the address of a label is just what LOC is meant for. The issue here may not be with LOC at all.
  • potatoheadpotatohead Posts: 10,253
    edited 2019-09-19 04:20
    If you think of LOC as the Motorola "Load Effective Address", ( LEA ) it's being used as intended.



Sign In or Register to comment.