Shop OBEX P1 Docs P2 Docs Learn Events
Newb assembly questions — Parallax Forums

Newb assembly questions

Daniel Lloyd-WoodDaniel Lloyd-Wood Posts: 14
edited 2009-08-18 20:59 in Propeller 1
Hello,

I'm trying to write some basic assembly. I need the program to test whether given pins are high·and·set a variable if they are.

This is what I've got so far:

VAR
 
  long  cog                           
  long  pin1
  long  pin2
  long  pin3
  long  sig_detected 'is set to 1 if signal is found on all given pins
 
PUB main

 
dira[noparse][[/noparse]15]~~
dira[noparse][[/noparse]14]~~
 
start(28,27,26)
 
repeat
  if sig_detected == 1
    outa[noparse][[/noparse]15]~~
  else
    outa[noparse][[/noparse]14]~~
  
PUB start(p1,p2,p3) : okay
 
pin1 := |< p1
pin2 := |< p2
pin3 := |< p3

 
okay := cog := cognew(@entry, @pin1) + 1
 
PUB stop
 
  if cog
    cogstop(cog~ -  1)
 
DAT
 
entry
                       'Get pointer
                        mov     p,par
 
                       'Move variables into cog memory 
                        rdlong  _pin1,p
                        add     p,#4
                        rdlong  _pin2,p
                        add     p,#4
                        rdlong  _pin3,p
                        add     p,#4

 
                       'Set up pinmasks
                        mov     _pinmask,_pin1
                        or      _pinmask,_pin2
                        or      _pinmask,_pin3

                       'Check pins
:loop                   mov     temp,ina          
                        
                       'Test ina against pinmask
                        test    temp,_pinmask wc  ---This is probably where it goes wrong. 
                        
                       'Break if matched 
                if_c    jmp     #:break
                         
                        jmp     #:loop
                        
                       'Write 1 to sig_detected
:break                  wrlong  istrue,p
 
                       'Set up time
                        mov     time,cnt
                        add     time,delay
                        
                       'Wait
                        waitcnt time,delay
 
                        jmp     #:loop   
                        
delay         long 40000
istrue        long 1
 
' Uninitialized data
_pinmask      res 1
_pin1         res 1
_pin2         res 1
_pin3         res 1
p             res 1
time          res 1
temp          res 1


I'm obvoiusly going wrong because it doesn't work.

I'm not sure how to get the pin mask to match ina and therefore test true, set wc and cause the loop to break. I'm also not sure how to only test the portion of ina relevant to the given pins. i.e. if there are inputs on other pins, not just 26,27,28 the mask will fail. How can·I test only 26,27,28 are high and ignore all other pins?

Some guidance would be greatly appreciated.

Many Thanks,

Dan

Comments

  • SRLMSRLM Posts: 5,045
    edited 2009-08-13 21:42
    Try using the AND command along with WZ and NR, or alternately the TEST command along with WZ.

    So, as long as your mask has a high bit for the pin in the right spot, then when you AND it with INA the rest of the numbers don't matter: your pin will be in !Z. Note that this only works for one pin at a time. I don't have any solutions for multiple pins beyond iterative testing.

    And, if you haven't given it a shot yet, try PASD for assembly debugging.

    Post Edited (SRLM) : 8/13/2009 10:00:43 PM GMT
  • AribaAriba Posts: 2,690
    edited 2009-08-13 22:55
    To compare the relevant bits of ina with the pinmask:
    :loop                   mov     temp,ina         
                           
                           'Test ina against pinmask
                            and    temp,_pinmask           'mask the relevant bits
                            cmp   temp,_pinmask wz      'compare
                            
                           'Break if matched
                    if_z    jmp     #:break
                            
                            ...
    
    



    Andy
  • Daniel Lloyd-WoodDaniel Lloyd-Wood Posts: 14
    edited 2009-08-16 17:39
    Very helpful as always. I've got it going now.
    Thanks guys.
  • Daniel Lloyd-WoodDaniel Lloyd-Wood Posts: 14
    edited 2009-08-18 20:46
    I've been messing about with my code and trying out some other ideas. I have come up with another question. How can you clear WZ once it has been set? Does it get cleared if 'CMP A,B WZ' does not match?
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2009-08-18 20:56
    Daniel Lloyd-Wood said...
    I've been messing about with my code and trying out some other ideas. I have come up with another question. How can you clear WZ once it has been set? Does it get cleared if 'CMP A,B WZ' does not match?
    It gets re-set every time WZ is used. I don't think you can "clear" it as the only two values are Z (1) and NZ (0)...so I guess it being cleared is the same as NZ (same goes for C).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    April, 2008: when I discovered the answers to all my micro-computational-botherations!
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-08-18 20:59
    Of course you can use any instruction that changes the value of the Z flag together with the WZ flag and the NR flag set if you don't want to change something else. CMP is the same as a SUB ... NR, so the NR flag is already set by the compiler per default. But you need to be sure that A and B conatain different values.

    So, an easier way would be
    MOV wherever, #1 NR
    to clear the Z flag and
    MOV wherever, #0 NR
    to set the Z flag
Sign In or Register to comment.