Shop OBEX P1 Docs P2 Docs Learn Events
Pasm munching squares help — Parallax Forums

Pasm munching squares help

JLSJLS Posts: 76
edited 2015-01-04 17:31 in Propeller 1
Hi all

I am begginer is possible help me how to make simple munching square with pasm routine ? (for fast graphic and for my basic teaching with pasm)

See my simple example with spin.

Many many thanks help

Kamil

Comments

  • AribaAriba Posts: 2,690
    edited 2015-01-03 16:25
    Here is draft of a possible code. It compiles but it's not tested.

    As you can see the Munching squares calculation is easy, just an XOR and an ADD.
    The plot subroutine is a bit more challenging... and you have to pass the screen address to the PASM cog, fortunatly there is getter methode for that in the VGA code.
    {{ Munching Squares - VGA }}
    
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    OBJ
      pix: "VGA64.spin"
    
    PUB demo
      pix.PIXEngineStart(2)                     'start VGA driver
      waitcnt(clkfreq/100 + cnt)                'wait 10ms
      cognew(@munch_asm, pix.displayPointer)    'start PASM cog
    
    DAT
    munch_asm     mov  screen,par               'pointer to sreenbuffer
                  mov  mt,#0                    'init t,x,y
    loopt         mov  my,#0
    loopy         mov  mx,#0                    'loop over x,y
    loopx         mov  mval,mx                  'calc: val := (x ^ y) + t
                  xor  mval,my                  
                  add  mval,mt
                  call #plot
                  add  mx,#1
                  cmp  mx,mwidth  wc
            if_b  jmp  #loopx
                  add  my,#1
                  cmp  my,mheight  wc
            if_b  jmp  #loopy
                  add  mt,#1
                  jmp  #loopt
    
    plot          mov  tmp,my                   'calc  screen address
                  shl  my,#5
                  shl  tmp,#7
                  add  tmp,my                   'my*32 + my*128 =^= mx*160
                  shr  my,#5                    'restore my
                  add  tmp,mx                   '+mx
                  add  tmp,screen               '+screen base addr
                  shl  mval,#2
                  or   mval,#3                  'color
                  wrbyte mval,tmp               'write into screen
    plot_ret      ret
    
    tmp           long 0
    mt            long 0
    mx            long 0
    my            long 0
    mval          long 0
    mheight       long 120
    mwidth        long 160
    screen        long 0
    
    you can copy and paste this into the Prop-Tool.

    Andy
  • JLSJLS Posts: 76
    edited 2015-01-04 08:19
    Hi Ariba

    Many many thanks this is working great :-)

    And this is my start point to learn with pasm !

    Simple question - is possible use modulo function in the pasm or must use modulo sub routine ?

    Many thanks !

    Kamil
  • ElectrodudeElectrodude Posts: 1,658
    edited 2015-01-04 08:50
    The propeller does not have multiply, divide, or modulo PASM instructions. You have to use subroutines for them.

    What base modulo are you trying to do? If the base is constant, you can make a custom routine that will be a lot faster. If the base is a power of 2, it's as simple as ANDing your value with (base - 1).
  • kwinnkwinn Posts: 8,697
    edited 2015-01-04 08:52
    You need to use a modulo subroutine. Propeller assembly instructions do not include more complex ones like multiply/divide/modulo. Those functions can be done with subroutines using adds/shifts/etc.
  • JLSJLS Posts: 76
    edited 2015-01-04 09:19
    Many thanks all about usefull info

    Do exist simple modulo subroutine ?
  • AribaAriba Posts: 2,690
    edited 2015-01-04 12:06
    This is a simple divide subroutine from Chip. The remainder is the Modulo result, so you need to shift the result right by 16 (shr x,#16).
    It works only with positive numbers and max. a 16bit divisor, but if you need it for graphics this should not be a problem.
    ' Divide x[31..0] by y[15..0] (y[16] must be 0) 
    ' on exit, quotient is in x[15..0] and remainder is in x[31..16] 
    ' 
    divide      shl y,#15         'get divisor into y[30..15] 
                mov t,#16         'ready for 16 quotient bits 
    :loop       cmpsub x,y wc     'if y =< x then subtract it, quotient bit into c 
                rcl x,#1          'rotate c into quotient, shift dividend 
                djnz t,#:loop     'loop until done 
    divide_ret  ret               'quotient in x[15..0], remainder in x[31..16]
    

    Andy
  • JLSJLS Posts: 76
    edited 2015-01-04 14:40
    Many thanks modulo working :-)

    See my example XOR Fractal
  • tonyp12tonyp12 Posts: 1,951
    edited 2015-01-04 14:53
    example: x=30 ,y=7
    30-7=23, 23-7=16, 16-7=9, 9-7=2
    Next cmpsub will not be approved for subtraction and c-flag will not be set, result modulo=2
    modulo                        'x original value, y the divider
    :loop       cmpsub x,y wc     'if y =< x then subtract it,
      if_c      jmp #:loop     
    modulo_ret  ret               'x=modulo
    


    As you don't need to know how many times, un-roll the loop a little will speed it up most of the time
    modulo                       'x original value, y the divider
    :loop       cmpsub x,y       'if y =< x then subtract it,
                cmpsub x,y       'if y =< x then subtract it,
                cmpsub x,y       'if y =< x then subtract it,
                cmpsub x,y wc    'if y =< x then subtract it,
      if_c      jmp #:loop     
    modulo_ret  ret               'x=modulo
    
  • msrobotsmsrobots Posts: 3,709
    edited 2015-01-04 17:31
    @tonyp12,

    nice code. the second one is almost mean. love it!

    Thanks!

    Mike
Sign In or Register to comment.