ASM - Move a BYTE into a LONG?
Ron Czapala
Posts: 2,418
I am trying to determine the best way to set the high order bits (above $1FF) using a the 8 bits in a BYTE into a LONG variable.
In the spin example below, how to accomplish this statement in PASM
LongVar.Byte[2] := bitmask
For example, the LEDs on the demo board are on pins 16 to 23.
If I have a BYTE variable that I want to set into OUTA to set those pins.
In spin it wouild like:
In the spin example below, how to accomplish this statement in PASM
LongVar.Byte[2] := bitmask
For example, the LEDs on the demo board are on pins 16 to 23.
If I have a BYTE variable that I want to set into OUTA to set those pins.
In spin it wouild like:
CON VAR long LongVar byte ByteVar PUB Main dira[16..23]~~ ' set to outputs ByteVar := %01010101 ' some changing bit pattern LongVar.Byte[2] := ByteVar outa := LongVar repeat
Comments
You can also reach certain places (easily) with movi/movd but a shift/rotate will always do the job.
When you execute this instruction, you are setting all 32 bits for OUTA.
This could affect other devices on those pins, correct?
mov outa, #%01010101
IF those bits are marked as outputs in dira then that's not an acceptable procedure. Otherwise it doesn't matter. If you want to insert stuff into a live outa then you need to prepare the data in a temporary register, e.g.
I need to investigate the REV instruction, but I used SHL instead.
I wasn't sure if a MOV longvar, bytevar would move the 8 bits into the lower 8 bits of the long but it does.
I was playing with this code which accepts keys entered the Serial Terminal and displays the binary value of the key on the Demo Board's LEDs on pins 16 thru 23.
Minor point, depending on timing the PASM part may pick up charval before it's reversed (SPIN is quite slow). You could probably initialise charval with the reverse of the rx method result directly.
I modified the code to use ANDN and OR to effect only bits 16-23 and eliminated the r1 variable. Good point about the PASM code picking up the value before it is reversed, but doesn't seem to be noticeable.
I am learning...
Thanks,
- Ron
Revised code:
Nice work! Yes, given how long the non-reversed state exist compared to the time it takes to send a new character it's hardly noticable. But it may lead to trouble when the wrong value is acted on. Not an issue for a simple display though.
Regarding rev, ATM you reverse the byte in SPIN (><) then shift it up by 16 in PASM. Now imagine you promote charval to a long and use >< 24 in SPIN instead of >< 8. What happens is that the lower 24 bits get mirrored and byte[0] ends up (reversed) in byte[2], right? Then let PASM pick up a long instead of a byte. This way you save the extra shl temp, #16 (in PASM).
Or you continue passing the raw byte value down to PASM and combine reversal and shift by using rev reg, #8 (in PASM the meaning is 32 - n where SPIN uses n).
HTH
The REV temp, #8 instruction really threw me for a while - I didn't see how the value ended up in bits 16-23.
After studying your helpful bit pattern comments, I could see that the lower 24 bits get reversed and the upper 8 cleared.
Thanks again,
- Ron
Spin Example 1 - Called as a Pasm function from Spin
Pasm Example
If you just want a clever way to do it in Spin you could do this...
Spin Example 2 - Variable aliasing
Thanks for the code examples. I just started learning PASM several days ago, so I was just experimenting with ways to manipulate data and using the Serial Monitor to get data to pass to PASM routines.
I also wanted a framework to test out [puzzle] PASM beginners only code.
Your variable aliasing example gave me pause until I remembered that data is stored in little-endian format.
Thanks again.