Setting OPx on based on time of day

Hmm, I just "found" a bunch of additional memory.
 

START    
    SET OP1 CS  
    SET VAR1 OP1  
    ADD 60 CS OP2
    SET VAR2 OP2  
end

 
Also some "bugs".
If you try to write numbers over about 128 to an output, it seems to break things.
If you output a number greater than 1 to an output, then use the output control to turn ttl output on and off, it only changes the LSB, the remaining bits persist.
 
Shift y bits to the left is same as X 2^y
like you pointed out, it will shift out the top bits.  To keep the top bits, first save the result of
/ 2^(32-y) into another variable, then after X 2^y, XORB the result with saved value.
 
It is not as elegant as you suggested having a rotate command, but it doable.
 
CAI_Support said:
Shift y bits to the left is same as X 2^y
like you pointed out, it will shift out the top bits.  To keep the top bits, first save the result of
/ 2^(32-y) into another variable, then after X 2^y, XORB the result with saved value.
 
It is not as elegant as you suggested having a rotate command, but it doable.
 
It's also not readily achievable. We don't have an exponentation operand.
Take a simple loop for example, scanning bits in a word (like my parity checker)
If RAM1 has a number from 0 to 16 and I want to convert that into a bit position,
   SHL 1 RAM1 RAM2     -> in one hit, puts the bit mask in RAM2.
 
To do it otherwise would require an iterative (and slow) loop and even more variables
   SET RAM2 1
   SET RAM3 RAM1  ; copy so we don't destroy the original value
shift:
   TSTEQ 0 RAM3
   GOTO done
   MUL RAM2 2 RAM2
   DEC RAM3
   GOTO SHIFT
done:
 
Erk!
 
Could you please help me understand the need more clearly.  When you say:
If RAM1 has a number from 0 to 16 and I want to convert that into a bit position,
SHL 1 RAM1 RAM2 -> in one hit, puts the bit mask in RAM2.
 
Do you mean RAM1 contains the bit position to set to 1?
 
The better understand the need, the better implementation would be.
Thanks.
 
Example by code fragment: This is a subroutine that reads serial bits and reassembles them in RAM1
 

READ:
    TSTNE IP1 1  
    GOTO READ   
R1:
    TSTNE IP1 0  
    GOTO R1   
    SET RAM2 17  
    SET RAM1 0  
    SET RAM3 1  
RDLP:
    DELAY VAR8   
    MUL RAM3 IP1 RAM4
    ADD RAM1 RAM4 RAM1
    MUL RAM3 2 RAM3
    DEC RAM2   
    BNZ  RDLP  
    RET  

 
 
Not terribly intuitive to read
 
A possible alternative with SHL

READ:
    TSTNE IP1 1  
    GOTO READ   
R1:
    TSTNE IP1 0  
    GOTO R1   
    SET RAM2 17  
    SET RAM1 0  
RDLP:
    DELAY VAR8   
    SHL IP1 RAM2 RAM3      ; shift input to weighted bit-position to reassemble
    ORB RAM1 RAM3 RAM1
    DEC RAM2   
    BNZ  RDLP  
    RET  

 
 
Similarly, the send code

SEND:
    SET OP1 1  
    DIV VAR8 2 RAM3
    DELAY RAM3   
    SET OP1 0  
    DELAY RAM3   
SENDLP:
    ANDB RAM1 1 OP1
    DELAY VAR8   
    DIV RAM1 2 RAM1
    DEC RAM2   
    BNZ  SENDLP  
    SET OP1 0  
    RET  

 
could be rewritten
 

SEND:
    SET OP1 1  
    DIV VAR8 2 RAM3
    DELAY RAM3   
    SET OP1 0  
    DELAY RAM3   
SENDLP:
    SHL 1 RAM2 RAM3      ; set mask bit
    ANDB RAM1 RAM3 OP1 ; this will work once the ANDB to an output bit is fixed
    DELAY VAR8   
    DEC RAM2   
    BNZ  SENDLP  
    SET OP1 0  
    RET  

 
May not save much code space, but makes the code more readable.
 
Thanks, Ross.
In your example, does the shift put the overflow bit into the lowest bit position? It seems
DIV VAR8 2 RAM3
in main routine will destory that RAM3 value anyway.
 
In my example, RAM3 is only used to calculate a half-bit interval which is used twice, then no longer required, and in the send loop it is only used for long enough to logical AND the mask with the send word and then it is no longer required either, so no issue with either. Only RAM1 (the word to be sent/received) and RAM2 (the number of bits to send/receive) are important.
 
Ross,
 
Can this be done in this way?
orig:
 
    SHL 1 RAM2 RAM3 ; set mask bit
    ANDB RAM1 RAM3 OP1 ; this will work once the ANDB to an output bit is fixed
 
using MOD operand:
 
    MOD RAM1 2 OP1
 
In this, MOD RAM1 by 2 is like shift RAM1 down 1 bit at a time, then the bit shifted out being used to set OP1
RAM1 is store the word to send, is shifted to the left to construct the word, shift to right by MOD to consume the word.

 
 
CAI_Support said:
Ross,
 
Can this be done in this way?
 No.
The problem you're missing is the variable number of bits to shift by. If it's just one bit at a time in a loop, there are any number of ways to do it.
But often times, it will simply be "some arbitary bit", not all bits in sequence up to a point.
 
That's why I suggested SHL (pattern) (number of bit positions) (destination)  (and SHR) although of course ROTL and ROTR would be handy for other reasons.
 
You mean overflow bits to put to the other end?  Are we always suppose the number is 32bit signed number?  When shift an 1 to the top bit, that number will become a negative number.
 
CAI_Support said:
You mean overflow bits to put to the other end?  Are we always suppose the number is 32bit signed number?  When shift an 1 to the top bit, that number will become a negative number.
 
With a rotate, you treat it just as a n-bit shift register. What pops out one end, goes in the other.
If it's a 32-bit (signed) number, its up to the programmer to decide how to interpret the number.
Lets just take it as a 4-bit number for now - the logic is identical.
 
Before   After ROTL    After ROTR
  0001      0010               1000
  0010      0100                0001
  0100      1000                0010
  1000       0001               0100
  1101       1011               1110
 
etc.
 
Ross,
 
You want to have ROTL and ROTR that
ROTL  x  y  z
ROTR  x  y  z
 
where takes X and rotate y bits and put result in z.
no zero bit set for these operation. 
Shifting can result a negative number that user must handle himself.
 
That is doable, we just want to make sure that is exactly the way you wanted.  Anybody has any other suggestion?
 
CAI_Support said:
If x is zero, the operation will not performed.
any PLC operation result zero will send up set up zero bit.
 
If x OR y is zero, the operation need not be performed.
If you're *offering* to replicate the shifted bit into the zero bit too, that'd be cool :)
Not really necessary, but nice. It would eliminate the need for a further test-after-rotate in many cases.
I agree it may produce a "negative number" in some cases - but this is largely just a convention, a 32-bit number is a 32-bit number, its only how you choose to handle the sign bit that makes it different. If we (the users) choose to use it as 32 bitflags, or a 32-bit unsigned integer or whatever, doesn't change the way the number is stored - just how we interpret it. So that's fine with me.
 
In our PLC engine, the zero bit is automatically set if the operator result is zero, including
SET VAR1 0
in the rotate function, if x or y is zero, then it will not rotate, the zero bit will never set.  Because set resuolt in z is last action of that line of PLC code, we don't have anyway to set zero bit, that will break the setoutput funciton.
I send you a PM
 
Back
Top