;Shifts an integer left by lit bits.
;intH: the address of the high byte of the integer. The low byte is assumed
; to be at the next address (intH+1) so that the integer is intH:intL.
;lit: the number of bits to shift left. Valid values are 1 to 15.
;Affects WREG and STATUS
;------------------------------------------------------------------------------
INT_SL macro intH, lit
local intL, cnt
intL = intH + 1
if lit < 9
if lit < 6
if lit < 4
cnt = lit
while cnt > 0
rlf intL, f
rlf intH, f
cnt--
endw
if lit == 1
bcf intL, 0
else
movlw low (0xFF << lit)
andwf intL, f
endif
else
movlw 0x0F ;intH: p1, p2. intL: p3, p4
andwf intH, f ;0, p2
swapf intH, f ;p2, 0
swapf intL, f ;p4, p3
andwf intL, w ;0, p3
iorwf intH, f ;p2, p3
xorwf intL, f ;p4, 0. intH: p2, p3. intL: p4, 0
if lit == 5
rlf intL, f
rlf intH, f
bcf intL, 0
endif
endif
else
if lit < 8
if lit < 7
rrf intH, f ;move intH[0] into carry
rrf intL, w ;move intH[0] to intL and intL[0] to carry
clrf intL ;set lower byte to zero
rrf intL, f ;make intL[0] into intL[7]
rrf intH, f ;move intH[1] into carry
movwf intH ;intH = intH[0]:intL[7-1]
rrf intH, f ;now intH = intH[1]:intH[0]:intL[7-2]
rrf intL, f ;now intL = intL[1-0]:ZEROS
else
rrf intH, f ;move intH[0] into carry
movf intL, w
movwf intH ;intH = intL
rrf intH, f ;intH = intH[0]:intL[7-1], intL[0] in carry
clrf intL ;intL = zero
rrf intL, f ;intL = intL[0]:zeros
endif
else
movf intL, w
movwf intH
clrf intL
endif
endif
else
if lit < D'14'
if lit < D'12'
movf intL, w
movwf intH
clrf intL
cnt = lit - 8
while cnt > 0
rlf intH, f
cnt--
endw
if lit == 9
bcf intH, 0
else
movlw low (0xFF << (lit - 8))
andwf intH, f
endif
else
swapf intL, w
if lit == D'12'
andlw 0xF0
endif
movwf intH
if lit == D'13'
rlf intH, f
movlw 0xE0
andwf intH, f
endif
clrf intL
endif
else
clrf intH
cnt = D'16'-lit
while cnt > 0
rrf intL, f
rrf intH, f
cnt--
endw
clrf intL
endif
endif
endm
;Shifts an integer right by lit bits.
;intH: the address of the high byte of the integer. The low byte is assumed
; to be at the next address (intH+1) so that the integer is intH:intL.
;lit: the number of bits to shift right. Valid values are 1 to 15.
;Affects WREG and STATUS
;------------------------------------------------------------------------------
INT_SR macro intH, lit
local intL, cnt
intL = intH + 1
if lit < 9
if lit < 6
if lit < 4
cnt = lit
while cnt > 0
rrf intH, f
rrf intL, f
cnt--
endw
if lit == 1
bcf intH, 7
else
movlw low (0xFF >> lit)
andwf intH, f
endif
else
movlw 0xF0 ;intH: p1, p2. intL: p3, p4
andwf intL, f ;p3, 0
swapf intL, f ;0, p3
swapf intH, f ;p2,p1
andwf intH, w ;p2, 0
iorwf intL, f ;p2, p3
xorwf intH, f ;0, p1. intH: 0, p1. intL: p2, p3
if lit == 5
rrf intH, f
rrf intL, f
bcf intH, 7
endif
endif
else
if lit < 8
if lit < 7
rlf intL, f ;move intL[7] into carry
rlf intH, w ;move intL[7] to intH and intH[7] to carry
clrf intH ;set upper byte to zero
rlf intH, f ;make intH[0] into intL[7]
rlf intL, f ;move intL[6] into carry
movwf intL ;intL = intH[6-0]:intL[7]
rlf intL, f ;now intL = intH[5-0]:intL[7-6]
rlf intH, f ;now intH = zeros:intH[7-6]
else
rlf intL, f ;move intL[7] into carry
movf intH, w
movwf intL ;intL = intH
rlf intL, f ;intL = intH[6-0]:intL[7], intH[7] in carry
clrf intH ;intH = zeros
rlf intH, f ;intH = zeros:intH[7]
endif
else
movf intH, w
movwf intL
clrf intH
endif
endif
else
if lit < D'14'
if lit < D'12'
movf intH, w
movwf intL
clrf intH
cnt = lit - 8
while cnt > 0
rrf intL, f
cnt--
endw
if lit == 9
bcf intL, 7
else
movlw low (0xFF >> (lit - 8))
andwf intL, f
endif
else
swapf intH, w
if lit == D'12'
andlw 0x0F
endif
movwf intL
if lit == D'13'
rrf intL, f
movlw 0x07
andwf intL, f
endif
clrf intH
endif
else
clrf intL
cnt = D'16'-lit
while cnt > 0
rlf intH, f
rlf intL, f
cnt--
endw
clrf intH
endif
endif
endm