Writing to an indirectly addressed register using FSR/IND
![Zoot](https://forums.parallax.com/uploads/userpics/559/nW4UO23UEIWZ4.png)
I'm slowly translating some SX/B code to assembly so I can use the code in an ISR and not worry about preserving PARAM vars. I've found that accessing virtual arrays has been my big code bottleneck and use of param vars, so I've been working on converting that code first.
Here is a snippet -- is this best (only?) way to do this kind of move, each time creating the dynamic address in the FSR and using IND as if it were the address (for a write) and if it was the value (if it is a read)? See the line commented "save it" to see what I mean.
POSTSCRIPT -- I just realized MOVB is a multiple word instruction, which means I need to presume that W will not be maintained... so do I need to use another work var in place of stuff like
MOV W, #ledVals
MOVB W.3, tmpB2.7
??
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
Here is a snippet -- is this best (only?) way to do this kind of move, each time creating the dynamic address in the FSR and using IND as if it were the address (for a write) and if it was the value (if it is a read)? See the line commented "save it" to see what I mean.
POSTSCRIPT -- I just realized MOVB is a multiple word instruction, which means I need to presume that W will not be maintained... so do I need to use another work var in place of stuff like
MOV W, #ledVals
MOVB W.3, tmpB2.7
??
'relevant var structure (SX28)..... ledData VAR Byte(16) leds VAR ledData(0) ledPin VAR ledData(8) ledTimer VAR ledData(9) ledIdx VAR ledData(10) ledTix VAR ledData(11) ledFrame VAR ledData(14) ' a word ledFrame_LSB VAR ledFrame ledFrame_MSB VAR ledData(15) ledVals VAR Byte(16) ledLos VAR ledVals(0) ledHis VAR ledVals(8) ledTmrsModes VAR Byte(16) ledRtmrs VAR ledTmrsModes(0) ledModes VAR ledTmrsModes(8) ' bit7 is direction 0 -> up; 1 -> down 'snippet..... IF tmpB1 = 1 THEN ' blink it ASM 'note: need to make sure idx, tmpB1, tmpB2 compile to global var space MOV W, #ledVals 'point to hi/lo 8 byte arrays MOVB W.3, tmpB2.7 'use dir bit from tmpB2 -- 0-7 = lows, 8-15 = highs ADD W, idx MOV FSR, W MOV tmpB1, IND 'get the val into free temp MOV W, #leds 'setup address for saved brightness ADD W, idx MOV FSR, W MOV IND, tmpB1 'save it BANK 0 ENDASM 'above translated from 'tmpB1 = idx 'tmpB1.3 = tmpB2.7 'leds(idx) = ledVals(tmpB1) ELSEIF ' etc....
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
Comments
It would probably work if you set bit 7 of the OPTION register and used "MOVB WREG.3,tmpB2.7". But your translation is not doing what the SX/B code would do ?
' tmpB1 = idx
' tmpB1.3 = tmpB2.7
' leds(idx) = ledVals(tmpB1)
ASM·' tmpB1 MUST be in global memory area
· MOV W,idx
· SB tmpB2.7
· AND W,#$F7 ' W.3 = 0
· SNB tmpB2.7
· OR W,#$08 ' W.3 = 1
· MOV FSR,W
· ADD FSR,#ledVals
· MOV tmpB1,IND
· BANK $00 ' Needed only if "idx" is NOT in globabl memory area
· MOV FSR,idx
· ADD FSR,#leds
· MOV IND,tmpB1
· BANK $00
· ' Warning: Does not leave tmpB1 with the same value as SX/B code
ENDASM
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My goal is to live forever...Or die trying.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.hittconsulting.com
Post Edited (Bean (Hitt Consulting)) : 10/22/2007 9:56:20 PM GMT
- so FSR can support bit instructions, etc.?
- difference between W and WREG?
- I think in your code correction (thank you) "ADD FSR, leds" should be "ADD FSR, #leds"
Am I off somewhere or not explaining it clearly?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
"W" is a special register that does NOT have a memory location, also the port configuration registers do NOT have a memory location.
"WREG" is an alias for "W" when OPTION.7=1, then memory location $01 is "W" when OPTION.7 = 0 then memory location $01 is RTCC.
P.S. I changed the code in the post above.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My goal is to live forever...Or die trying.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.hittconsulting.com
·
Last stupid question of the day (I think) -- so register $01 can be used to read/write W (as a regular register, i.e. WREG) and RTCC by setting/clearing bit7? If it's set to 0 that doesn't affect actual value of RTCC unless I mess with it, right?
OPTION.7 is 1 by default?
OPT is like a port register so you can't set bits on it, only the whole byte? e.g.
AND !OPTION, #%0111_1111
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
OPTION.7 is zero by default (RTCC).
Right OPTION is like the port control registers, you must set the whole byte. Although there is a "secret" instruction that allows you to "MOV W,OPTION". Then you can modify W and do "MOV OPTION,W". In affect just changing the bits you want changed.
I tend to avoid using "WREG". As you can see in my code, you can set or clear bits in "W" using AND and OR. And it only uses 1 instruction.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My goal is to live forever...Or die trying.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.hittconsulting.com
·