Assembly P1 to P2 question
in Propeller 2
I am converting the P1 shift register to P2. I am not an assembly guy by any means.
I am working through it, but I have hit a hurdle I cant get over.
The and line here is the problem.
FlexProp gives the following error:
"error: syntax error, unexpected identifier `nr', expecting instruction modifier"
I am working through it, but I have hit a hurdle I cant get over.
The and line here is the problem.
FlexProp gives the following error:
"error: syntax error, unexpected identifier `nr', expecting instruction modifier"
DAT shift_bits
mov count, #8 ' Shift 8 bits (one chip)
.shift_bit
shl shiftout, #1 ' Move next bit up out of shiftout
and shiftout, #$100 wc,nr ' Read MSB; store it in carry flag
muxnz outa, srclk ' Make clock low
muxc outa, srdata ' Output the consumed bit to the shift register
nop ' Let data line settle (this nop is optional)
muxz outa, srclk ' Clock high to latch bit of data
djnz count, #.shift_bit ' Do next bit
shift_bits_ret ret
Comments
Fortunately for you, "and x, y nr" is equivalent to "test x, y". So to make this work on the P2 just change the "and" instruction to "test" and remove the "nr".
Give this a try:
pub shiftout(b) org rep #6, #8 ' repeat 6 instructions 8x drvl SCLK ' clock low testb b, #7 wc ' get msb (bit7) into C drvc SDAT ' output C on SDAT pin nop ' let it settle drvh SCLK ' clock low shl b ' prep next bit end
Note that SCLK and SDAT are pin constants, they are not masks (as required in the P1). The drvx instructions take care of setting the IO level and the pin state to output.Is it better to use inline rather than put it all in the dat section ? I know I have seen some really bad C with in-line assembly that was barely legible. Wouldn't it make readability and maintainability better if it was separated ?
One bad thing is there are limits to the complexity of the code that can be inline.
Something like this.
pub main() pinh(58) repeat pint(58) call(@blink) dat orgh blink drvnot #56 waitx ##25_000_000 / 5 ret
Wow, is that a new thing? I'm not sure I knew about "CALL".
Wonder if that works in FlexProp...
In cases where the inline PASM code wouldn't fit within $140 longs I expect it should still be possible to just preserve the additional COG registers and LUT RAM that normally needs to be avoided by the called PASM code so you can make even more use of the COG's resources before restoring these registers when it returns back to SPIN2. SETQ[2] transfer bursts would help there. There will be extra overhead for these steps, but in some applications it could still be useful. The HW stack may also need to be preserved if that also needs to be used by the PASM code.
EDIT. Actually I guess this situation won't really arise due to "not fitting" if this CALL is simply executing in hub-exec mode anyway, more likely to be needed if the inline PASM wanted to use the LUT resource or need more than the first $140 longs for it's data purposes perhaps.
I know outa can be replaced with drvl. But it doesn't work. I think it has something to do with mux. I don't quite understand what mux does, but if I remove it and just use drvl it compiles ad runs, but I am not getting the expected results.
I have attached the object for further reference.
shift_bits mov count, #8 ' Shift 8 bits (one chip) .shift_bit shl shiftout, #1 ' Move next bit up out of shiftout test shiftout, #$100 wc ' Read MSB; store it in carry flag muxnz outa, srclk ' Make clock low muxc outa, srdata ' Output the consumed bit to the shift register nop ' Let data line settle (this nop is optional) muxz outa, srclk ' Clock high to latch bit of data djnz count, #:shift_bit ' Do next bit ret
The load_ and store_states subroutines need more nop's with P2, I think, but there is a better way for indirect access of cogram on P2:
store_states altd arg1_, #out_states mov 0, shiftout ret load_states alts arg1_, #out_states mov shiftout, 0 ret
But the main question is: Is this just an exercise to learn PASM2, or is your goal a good object for these shift registers?
In the second case, it makes no sense to start another cog to do some PASM code with the Prop2. There is inline PASM which runs in the same cog, or even better you can use pure Spin2, without PASM for such tasks. Spin2 is much, much faster than Spin on the P1.
Attached is a Spin2 only version, shifting 1 bit takes under 3us with Chips Spin2 and about 1 us with fastspin at 180MHz sysclock. I have not testet it with real chips, but checked the signals on a scope.
Andy
Thanks for the help. I will take a look at it later today.
looking again at this section:
and convert it from p1
why does the and line not work here ? At least I think that is where it breaks
I am more on a quest to learn assembly at this point!
shift_bits mov count, #8 ' Shift 8 bits (one chip) .shift_bit shl shiftout, #1 ' Move next bit up out of shiftout and shiftout, #$100 wc ' Read MSB; store it in carry flag drvl srclk ' Make clock low drvc srdata ' Output the consumed bit to the shift register nop ' Let data line settle (this nop is optional) drvh srclk ' Clock high to latch bit of data djnz count, #.shift_bit ' Do next bit ret
shift_bits mov count, #8 ' Shift 8 bits (one chip) .shift_bit shl shiftout, #1 ' Move next bit up out of shiftout {*} testb shiftout, #8 wc ' Read MSB; store it in carry flag drvl srclk ' Make clock low drvc srdata ' Output the consumed bit to the shift register nop ' Let data line settle (this nop is optional) drvh srclk ' Clock high to latch bit of data djnz count, #.shift_bit ' Do next bit ret
My habit is to pre-shift the bits so that the shift left can get the MSB into C.shift_bits shl shiftout, #24 ' move msb to shiftout.[31] rep #5, #8 ' repeat next 5 instructions 8x shl shiftout, #1 wc ' get msb drvl srclk ' clock low drvc srdata ' write data nop ' let data settle drvh srclk ' clock high ret
Using rep (repeat), you can save a variable since you're always shifting 8 bits.and shiftout, #$100 wc ' Read MSB; store it in carry flag
The C flag will contain the parity of the result not the msb.For a single bit (e,g. a mask of $100) the parity and value are the same, which is sometimes convenient.