Dmitry Kiryashov [zews at AHA.RU] says:
...to convert byte mask back into number. I suggest that somebody else probably has successfully researched this before. This is what I've discovered... It takes 12 clocks/words; W before -> W after ; abcdefgh -> 00000ABC ; 10000000 -> 7 = 4+2+1 ; 01000000 -> 6 = 4+2+0 ; 00100000 -> 5 = 4+0+1 ; 00010000 -> 4 = 4+0+0 ; 00001000 -> 3 = 0+2+1 ; 00000100 -> 2 = 0+2+0 ; 00000010 -> 1 = 0+0+1 ; 00000001 -> 0 = 0+0+0 movwf temp ;save abcdefgh swapf temp,W ;efghabcd xorwf temp,F ;........ andlw 0xF ;0000abcd skpz movlw 4 ;load A=0/4 btfss temp,3 btfsc temp,2 iorlw 2 ;add B=0/2 btfss temp,3 btfsc temp,1 iorlw 1 ;add C=0/1 ;W holds 7..0 of result
Marc [marc at AARGH.FRANKEN.DE] says:
You can make it a table-read, and fill the gaps with other sub functions. Under the presumption that you can make use of any area of 3+ words in size, this method uses 6 cycles (incl call/ret) and 11 words.addwf pc,f (1 wasted word) retlw 0 retlw 1 (1 wasted word) retlw 2 (3 spare words) retlw 3 (7 spare words) retlw 4 (15 spare words) retlw 5 ...
Code:
;Gonzalo Barco ;A looped approach (a bit smaller and lot slower) ;In case you are sure there's at least one bit set you can loose the first bsf COMPACT4BIT MACRO FILE ;Returns bit 3 set on error (no bits set) local loop, tail bsf STATUS, C ;To be sure we don't looooooooooooop forever clrw ;Clear counter loop: rrf FILE, F ;Send bits off the edge... btfsc STATUS, C ;...on to STATUS, C goto tail ;If we hit the bit... stop addlw 1 ;Otherwise add to the counter... goto loop ;...and keep looping tail: movwf FILE ;Overwrite source with result ENDM
Comments: