Shop OBEX P1 Docs P2 Docs Learn Events
Assembler - strange behaviour — Parallax Forums

Assembler - strange behaviour

GrahamSGrahamS Posts: 4
edited 2011-05-12 00:02 in Propeller 1
Hi,

Not sure if its me - BUT - I am getting some very strange results when trying to use the MOVD instruction :



'32bit block done
blkstore mov 0-0, bitbuf 'now save incoming 4 char block NB MUST set DEST!!!
add p_IN, #$1 'set up pointer for next block
'mov p_IN, #cmdIN
'nop
movd blkstore, p_IN 'set dest storage cell
djnz blkcnt, #spi_char 'now if not all done - go get next block
''all done
wrlong p_IN, par

Notice the two commented out lines

p_IN is set earlier in the app to #cmdIN, so the following occurs :

1. if I comment out the add and uncomment the nop p_IN reports as being 36h

2. If I comment out the nop and uncomment the line above it p_IN reports 36

So far So GOOD ;-)).

3. If I comment out the line from 2 and uncomment the add line - p_IN reports as 38 (ie 2 more than it was previously!!).

OK - so what am I doing stupid here please anyone ????.

Also - if I try to compare the hex listing (Ctrl-F8), I see that my register numbers are 6 cells (24 bytes) out The above test on a running board shows cddIN as register 36 - but it appears at byte location 0FC (which is 36 * 4 + 24) :-O is this explained somewhere ??.

Sorry but I am pretty new to the Propeller - but have it already designed into a couple of PCB's :-O.

Many Thanks

Apologies if its something stupid I am doing (probably ;-).

Best regards

Graham

Comments

  • tonyp12tonyp12 Posts: 1,951
    edited 2011-05-11 11:11
    don't forget to use code brackets
    And do you initialize the D field at some prior point?
    You don't have to use p_IN.
    If you just want to add 1, you can simple add %1<<9
    as that value is higher than 511, it will need to be stored a data
                                    '32bit block done
    blkstore mov 0-0, bitbuf        'now save incoming 4 char block NB MUST set DEST!!!
             add p_IN, #$1          'set up pointer for next block
    '        mov p_IN, #cmdIN
    '        nop
             movd blkstore, p_IN    'set dest storage cell
             djnz blkcnt, #spi_char 'now if not all done - go get next block 
    '                               'all done
             wrlong p_IN, par
    
  • AleAle Posts: 2,363
    edited 2011-05-11 11:12
    Can you maybe post a bit more code ?... and surround the code by the corresponding tags code and /code enclosed in square brackets :)

    Where is blkstore destination initially set ? wouldn't make maybe more sense to set its destination first and then use the mov ?
  • GrahamSGrahamS Posts: 4
    edited 2011-05-11 15:07
    Guys,

    No problem - will post the code below. Its the start of an SPI interface, as the obex ones don't seem to have a timeout - ie they use waitpeq :-((.

    Thanks

    Graham

    Like this ??
    DAT           org       0
    '  
    ' SPI Engine - setup
    'dummy        long      $aaaaaaaa
    dospi         mov       dira, #$120                     'pin5 is data output
                  mov       outa, #$020                     'start it with high and no led
                  mov       blkcnt, #2
                  mov       dIN, #0
                  
    ' SPI Engine - main loop
    spiloop       mov       p_spiOUT, par                   'par is start of HUB data structures
                  add       p_spiOUT, #(5 << 2)             'plus offset bytes
                  mov       p_OUT, #cmdOUT                  ' now local data pointer 
                  rdlong    cmdOUT, p_spiOUT        wz      'read output command from HUB
                  'wrlong   countme, p_data
            if_nz jmp       #spi_output                     'ooh we got a command - so go handle it
    
    spi_input
    'first we need to wait for a start of clock cycle. Clock is normally LOW
                  test      spiCLKmask,ina          wz      'Test input pin. Is it low?
            if_nz jmp       #spiloop                        'oops waiting for a low clock!!
    
                  mov       p_IN, #cmdIN                    'local data pointer
                  movd      blkstore, p_IN                  'local data pointer
                  mov       time, timeout                   'start timeout
    spi_char
                  mov       bitbuf, #$1aa
                  mov       bitcnt, #32
                  
    :loop         test      spiCLKmask,ina          wz      'Test input pin. Is it low?
            if_z  djnz      time,#:loop             wz      'No: Go back and check again.
            if_z  jmp       #spitimeout                        'At this point the z flag will indicate whether we timed out or not.
                                                            'if we got here we should have a high clock pin      
    :loop1        test      spiCLKmask, ina         wz      'so wait for it to come low again
            if_nz djnz      time,#:loop1            wz      'No: Go back and check again.
                  testn     time, #0                wz
            if_z  jmp       #spitimeout
    
                  shl       bitbuf, #1
                  test      spiINPmask, ina         wz      'go get our data bit
            if_nz add       bitbuf, #$01
                  djnz      bitcnt,#:loop                   'if we have not done all bit go round again
    '32bit block done
    blkstore      mov       0-0, bitbuf                     'now save incoming 4 char block NB MUST set DEST!!!
                  add       p_IN, #$1                       'set up pointer for next block
                  'mov      p_IN, #cmdIN
                  'nop
                  movd      blkstore, p_IN                  'set dest storage cell
                  djnz      blkcnt, #spi_char               'now if not all done - go get next block                            
    ''all done
                  wrlong    p_IN, par
                  'mov      outa, #$120                     'OK so input is high, so wait for it to come low again
                  jmp       #spiloop
    
    spitimeout    mov       outa, #$120
                  jmp       #spiloop
    spi_output
                  add       p_spiOUT, #4                    'point to first data byte
                  rdlong    dOUT, p_spiOUT                  'read output command from HUB
                  add       p_spiOUT, #4                    'point to first data byte
                  rdlong    dOUT2, p_spiOUT                 'read output command from HUB
                  add       p_spiOUT, #4                    'point to first data byte
                  rdlong    dOUT3, p_spiOUT                 'read output command from HUB
                  add       p_spiOUT, #4                    'point to first data byte
                  rdlong    dOUT4, p_spiOUT                 'read output command from HUB
                  mov       p_OUT, #cmdOUT                  ' now local data pointer 
    
    
    ''all done
                  jmp       #spiloop
    '------------------------------------------------------------------------------------------------------------------------------
    timeout       long      80_000_000 / 10         '1/10th second at 80MHz
    spiINPmask    long      1 << 4                  'port bit 4
    spiOUTmask    long      1 << 5                  'port bit 5
    spiCLKmask    long      1 << 6                  'port bit 6
    spiSELmask    long      1 << 7                  'port bit 7
    
    'pointers to HUB input and output structures                       
    p_spiIN       long      0
    p_spiOUT      long      0
    
    'pointers to local COG RAM data structures
    p_IN          long      0
    p_OUT         long      0
    
    'local command structure
    'NB mirrored in HUB RAM
    cmdIN         long      $aa     '4 bytes of command header
    dIN           long      $bb     '16 bytes of data
    dIN2          long      $cc
    dIN3          long      $dd
    dIN4          long      $ee
    
    cmdOUT        long      0       '4 bytes of command header
    dOUT          long      0       '16 bytes of data
    dOUT2         long      0
    dOUT3         long      0
    dOUT4         long      0
    
    'local data
    countme       res       1
    time          res       1
    bitbuf        res       1
    bitcnt        res       1
    blkcnt        res       1
    
    
                  fit 496
    
    
    Ale wrote: »
    Can you maybe post a bit more code ?... and surround the code by the corresponding tags code and /code enclosed in square brackets :)

    Where is blkstore destination initially set ? wouldn't make maybe more sense to set its destination first and then use the mov ?
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-05-11 16:03
    You never reset blkcnt
    you need to move
    mov blkcnt, #2

    to or below spiloop

    as here your are decreasing it.
    djnz blkcnt, #spi_char 'now if not all done - go get next
  • kuronekokuroneko Posts: 3,623
    edited 2011-05-11 18:30
    GrahamS wrote: »
    '32bit block done
    blkstore        mov 0-0, bitbuf 'now save incoming 4 char block NB MUST set DEST!!!
                    add p_IN, [COLOR="red"]#$1[/COLOR] 'set up pointer for next block
                    'mov p_IN, #cmdIN
                    'nop
                    movd blkstore, p_IN 'set dest storage cell
                    djnz [COLOR="red"]blkcnt[/COLOR], #spi_char 'now if not all done - go get next block
    ''all done
                    wrlong p_IN, par
    
    3. If I comment out the line from 2 and uncomment the add line - p_IN reports as 38 (ie 2 more than it was previously!!).
    From your more verbose listing it transpires that blkcnt is 2 which means your loop runs twice therefore adding #$1 twice, $36+$1+$1 = $38. Am I missing something here?
    GrahamS wrote: »
    Also - if I try to compare the hex listing (Ctrl-F8), I see that my register numbers are 6 cells (24 bytes) out The above test on a running board shows cddIN as register 36 - but it appears at byte location 0FC (which is 36 * 4 + 24) :-O is this explained somewhere ??.
    That's normal. The binary file you see in the hex listing includes header info & Co, i.e. the first DAT block doesn't start at 0. One way to figure out the difference is to compile with F9 then place the cursor at the label you're interested in. The status line then tells you object location and cog location, e.g. I took your verbose example from post #4 added a dummy PUB method and compiled it. cmdIN reports $E0 object offset and $36 cog offset. Now, the binary file can have more than one object but the top level object is stored at offset $10 (in fact at offset word[3] of the binary file which amounts to the same right now). That gives us a file offset of $E0+$10 = $F0. Looking there reveals a long $AA. HTH
  • GrahamSGrahamS Posts: 4
    edited 2011-05-11 23:54
    Guys,

    Many many thanks - you saved my sanity !!. Of course it gets bumped twice as I am indeed running through the code twice :-O. Told you it was something stupid.

    Still the upside is that when you have to get down and dirty at this level - boy do you learn a lot and quickly ;-).

    Still trying to master the assembler addressing modes (or lack of) :-O - coming from a wide variety of different microprocessor chips - right back to the 6800 ;-). For me 'dynamic' self-modifying code has ALWAYS been a NO-NO !! - as my background (way-back) was in EPROM-based designs - where you just CANNOT do that!.

    Also many thanks to kuroneko - for the tip on the status bar after compilation. That will save me some time.

    Thanks for your patience guys, as you can see - I am new to this CPU, so getting into assembler with little or nor real-time debugging isn't easy ;-)).

    Best Regards

    Graham
    kuroneko wrote: »
    From your more verbose listing it transpires that blkcnt is 2 which means your loop runs twice therefore adding #$1 twice, $36+$1+$1 = $38. Am I missing something here?


    That's normal. The binary file you see in the hex listing includes header info & Co, i.e. the first DAT block doesn't start at 0. One way to figure out the difference is to compile with F9 then place the cursor at the label you're interested in. The status line then tells you object location and cog location, e.g. I took your verbose example from post #4 added a dummy PUB method and compiled it. cmdIN reports $E0 object offset and $36 cog offset. Now, the binary file can have more than one object but the top level object is stored at offset $10 (in fact at offset word[3] of the binary file which amounts to the same right now). That gives us a file offset of $E0+$10 = $F0. Looking there reveals a long $AA. HTH
  • GrahamSGrahamS Posts: 4
    edited 2011-05-12 00:02
    You are bang on there ;-). The blkcnt initialisation was indeed in the wrong place. Hadn't got as far as debugging that part yet - but it does explain why in bombed every so often ;-).

    Thanks for your input ;-).

    G.
    tonyp12 wrote: »
    You never reset blkcnt
    you need to move
    mov blkcnt, #2

    to or below spiloop

    as here your are decreasing it.
    djnz blkcnt, #spi_char 'now if not all done - go get next
Sign In or Register to comment.