Shop OBEX P1 Docs P2 Docs Learn Events
Sharing memory — Parallax Forums

Sharing memory

Hello all.

Someone now I am working on a system with an Propeller and an i4004 processor. I do this in Spin on this moment. But a part of the system I want to rewrite in Pasm for the speed.

http://forums.parallax.com/discussion/164728/i4004-robot

To develop this I take little step's. 1 Step is to understand how to use the sharing of a lot off memory between Spin and Pasm. In the following program I try to fill a blok of 256 byte's in HUB-ram by Spin and try to read this in a COG programmed in Pasm.
It is not working, what do I wrong:
VAR

  byte  temp
  byte  Rom[257]
 

PUB Start_1 | errorString 
 
  Rom[256] := 128                                      ' bitje mbt laden ROM

' *************************************************************************                                            
  Temp := 0                                                

  repeat 250
    Rom[temp] := temp
    temp := temp + 1
    

  waitcnt(80_000_000 + cnt)                            ' Wacht 1 seconde       
  cognew(@Rom_test, @Rom)                              ' Start de "Rom_test" Cog
  waitcnt(80_000_000 + cnt)                            ' Wacht 1 seconde
  
  repeat                                                ' Never stop


' ************************************************************************* 

DAT
              org       0
Rom_test      mov       dira,   led                     ' Maak LED uitgang
              mov       outa,   led                     ' Zet LED AAN (= toggle)
              xor       outa,   led                     ' Toggle/Knipper LED
              
              mov       lus1,   #0
              mov       lus3,   #100
              
wacht         mov       mem,    par                      
begin         add       mem,    #lus1                       'or #1 ??
              rdlong    uit,    mem
              add       lus1,   #4                      ' verhoog lus1 met 4 = next long
              mov       outa,   uit                     ' display LED
              mov       lus2,   #pauze                   ' 20_000_000 * 4 clockpuls = 1 Second
vertr         sub       lus2,   #1 wz
              if_nz     jmp     #vertr
              sub       lus3,   #1 wz                   
              if_nz     jmp     #wacht
              mov       lus3,   #60                    ' 60 numbers to Go                                                                             
              jmp       #wacht
'======================================================================
{Hier staan de declaraties van de variable}  '
            '
led        long         %00000000_00000000_00000000_11111111 ' output
pauze      long         20_000_000
tijd       long         100
         
lus1       res          1
lus2       res          1
lus3       res          1
uit        res          1
mem        res          1

fit

I try to display each second the next part of the next long on the output-LED's


Another question I have is: When i store data as byte in Hub-ram as followed:

Ram[0] = $H00
Ram[1] = $H11
Ram[2] = $H22
Ram[3] = $H33
Ram[4] = $H44
Ram[5] = $H55
Ram[6] = $H66

And I read it as long, how is it displayed:

long[00_11_22_33] or long[33_22_11_00]

Greetings Abraham.

Comments

  • kwinnkwinn Posts: 8,697
    You need to start another cog to run the PASM code and pass it the address of the first long in the array. The cog that is executing the spin interpreter code cannot execute the PASM code.
  • AribaAriba Posts: 2,690
    edited 2016-08-10 13:05
    Your ROM array must start at a long aligned address (the PAR passing at cognew needs that), so declare the temp variable as a long.

    Your PASM code has some little mistakes so I just show a corrected version with some hints.
    VAR
    
      long  temp
      byte  Rom[257]
     
    
    PUB Start_1 | errorString 
     
      Rom[256] := 128                                      ' bitje mbt laden ROM
    
    ' *************************************************************************                                            
      Temp := 0                                                
    
      repeat 250
        Rom[temp] := temp
        temp := temp + 1
        
    
      waitcnt(80_000_000 + cnt)                            ' Wacht 1 seconde       
      cognew(@Rom_test, @Rom)                              ' Start de "Rom_test" Cog
      waitcnt(80_000_000 + cnt)                            ' Wacht 1 seconde
      
      repeat                                                ' Never stop
    
    
    ' ************************************************************************* 
    
    DAT
                  org       0
    Rom_test      mov       dira,   led                     ' Maak LED uitgang
                  mov       outa,   led                     ' Zet LED AAN (= toggle)
                  xor       outa,   led                     ' Toggle/Knipper LED
                                              '<-- Not necessary: The LEDs are too short ON to see it
                                              '    OUTA is already cleared at start of a cog 
                  mov       lus1,   #0
                  mov       lus3,   #100
                  
    wacht         mov       mem,    par       '<-- Start with first Address of array                
    begin         rdbyte    uit,    mem       '<-- You should read a byte array with RDBYTE
                  add       mem,    #1                      ' next byte
                  mov       outa,   uit                     ' display LED
                  mov       lus2,   pauze                   ' 20_000_000 * 4 clockpuls = 1 Second 
                                              '<-- #pauze will give you the address, not the value 20000000
    vertr         djnz      lus2,   #vertr    '<-- decrement and jump in one Instruction = 4 clocks
    
                  sub       lus3,   #1 wz     '<-- in two instructions = 8 clocks              
                  if_nz     jmp     #wacht
                  mov       lus3,   #60                    ' 60 numbers to Go                                                                             
                  jmp       #wacht
    '======================================================================
    {Hier staan de declaraties van de variable}  '
                '
    led        long         %00000000_00000000_00000000_11111111 ' output
    pauze      long         20_000_000
    tijd       long         100
             
    lus1       res          1
    lus2       res          1
    lus3       res          1
    uit        res          1
    mem        res          1
    


    To your second question:

    Ram[0] is in the lowest byte
    Ram[3] is in the highest byte
    How it's displayed depends on the display routine ;)


    Andy
  • Ariba wrote: »
    Your ROM array must start at a long aligned address (the PAR passing at cognew needs that), so declare the temp variable as a long.

    Your PASM code has some little mistakes so I just show a corrected version with some hints.


    Andy

    Hello Andy.

    Thanks for your sugestion's, I go use it.

    Greeting Abraham

  • Ariba wrote: »
    Your ROM array must start at a long aligned address (the PAR passing at cognew needs that), so declare the temp variable as a long.

    Andy

    Hello Andy.

    Thanks voor your time and advice. This little step works so I go to set the next one. When I have made progress with my system i let it now.

    Greeting Abraham.
  • If you just want to speed up your Spin code, and if it's not too large, then you can compile it to PASM using spincvt.

    For example, your initial loop gets compiled to code that looks like:
    DAT
    	org	0
    entry
    
    ' 
    ' VAR
    ' 
    '   byte  temp
    '   byte  Rom[257]
    '  
    ' 
    ' PUB Start_1 | errorString 
    _Start_1
    '  
    '   Rom[256] := 128                                      ' bitje mbt laden ROM
    	mov	Start_1_tmp001_, #128
    	add	objptr, #257
    	wrbyte	Start_1_tmp001_, objptr
    	sub	objptr, #257
    ' 
    ' ' *************************************************************************                                            
    '   Temp := 0                                                
    	mov	Start_1_tmp001_, #0
    	wrbyte	Start_1_tmp001_, objptr
    ' 
    '   repeat 250
    	mov	_Start_1__idx__0001, #250
    L__0002
    '     Rom[temp] := temp
    	add	objptr, #1
    	mov	Start_1_tmp001_, objptr
    	sub	objptr, #1
    	rdbyte	Start_1_tmp002_, objptr
    	add	Start_1_tmp001_, Start_1_tmp002_
    	rdbyte	Start_1_tmp003_, objptr
    	wrbyte	Start_1_tmp003_, Start_1_tmp001_
    '     temp := temp + 1
    	rdbyte	Start_1_tmp001_, objptr
    	add	Start_1_tmp001_, #1
    	wrbyte	Start_1_tmp001_, objptr
    	djnz	_Start_1__idx__0001, #L__0002
    '   repeat                                                ' Never stop
    L__0005
    	jmp	#L__0005
    _Start_1_ret
    	ret
    
    Start_1_tmp001_
    	long	0
    Start_1_tmp002_
    	long	0
    Start_1_tmp003_
    	long	0
    _Start_1__idx__0001
    	long	0
    arg1
    	long	0
    arg2
    	long	0
    arg3
    	long	0
    arg4
    	long	0
    objptr
    	long	@@@objmem
    result1
    	long	0
    	fit	496
    	long
    objmem
    	long	$00000000
    

    Note that the object access model used by spincvt may not always be the same as that in the original Spin interpreter (for example, local variables are usually turned into COG addresses rather than placed on the stack). But spincvt can compile the whole program into a .binary file, which can then be run just like a Spin .binary file, but 10x faster (and probably 3x larger in size).
Sign In or Register to comment.