Pic Assembler Ohjeita
PIC ASM matematiikkarutiineja
Muuttujat tarvitsevat 26 byteä RAM tilaa kaikille runiineille yhdessä
DIGIT1 -DIGIT10 pitää olla jatkuvia muistipaikkoja.
; =====SIGNED 32-BITTIN INTEGER MATEMATIIKKARUTIINIT MICROCHIP pic16-sarjalle
;
;Funktiot:
; add
; subtract
; multiply
; divide
; round
; sqrt
; bin2dec
; dec2bin
;Muuttujat
mathram equ 30 ;(30 RAM alkuosoite, vaihda oman ohjelmasi mukaan )
cblock mathram ; varaa muistia seuraavia muutujia varten alkaen mathram paikasta
REGA0 ;lsb
REGA1
REGA2
REGA3 ;msb
REGB0 ;lsb
REGB1
REGB2
REGB3 ;msb
REGC0 ;lsb
REGC1
REGC2
REGC3 ;msb
DSIGN ;Digitin merkki 0=positiivinen,1=negatiivinen
DIGIT1 ;MSD
DIGIT2
DIGIT3
DIGIT4
DIGIT5 ;Decimal (BCD) digits
DIGIT6
DIGIT7
DIGIT8
DIGIT9
DIGIT10 ;LSD
MTEMP
MCOUNT
DCOUNT
endc
;*** 32 BIT SIGNED vähennyslasku ***
;REGA - REGB -> REGA
;Return carry bit asetettu jos ylivuoto
subtract
call negateb ;Negate REGB
skpnc
return ;Overflow
;*** 32 BIT SIGNED summaus ***
;REGA + REGB -> REGA
;Return carry bit asetettu jos ylivuoto
add movf REGA3,w ;Compare signs
xorwf REGB3,w
movwf MTEMP
call addba ;add REGB to REGA
clrc ;Check signs
movf REGB3,w ;If signs are same
xorwf REGA3,w ;so must result sign
btfss MTEMP,7 ;else overflow
addlw 0x80
return
;*** 32 BIT SIGNED KERTOLASKU ***
;REGA * REGB -> REGA
;Return carry bit asetettu jos ylivuoto
multiply
clrf MTEMP ;Reset sign flag
call absa ;Make REGA positive
skpc
call absb ;Make REGB positive
skpnc
return ;Overflow
call movac ;Move REGA to REGC
call clra ;Clear product
movlw D'31' ;Loop counter
movwf MCOUNT
muloop call slac ;Shift left product and multiplicand
rlf REGC3,w ;Test MSB of multiplicand
skpnc ;If multiplicand bit is a 1 then
call addba ;add multiplier to product
skpc ;Check for overflow
rlf REGA3,w
skpnc
return
decfsz MCOUNT,f ;Next
goto muloop
btfsc MTEMP,0 ;Check result sign
call negatea ;Negative
return
;*** 32 BIT SIGNED JASKOLASKU ***
;REGA / REGB -> REGA
;Remainder in REGC
;Return carry bit asetettu jos ylivuoto tai jako nollalla
divide clrf MTEMP ;Reset sign flag
movf REGB0,w ;Trap division by zero
iorwf REGB1,w
iorwf REGB2,w
iorwf REGB3,w
sublw 0
skpc
call absa ;Make dividend (REGA) positive
skpc
call absb ;Make divisor (REGB) positive
skpnc
return ;Overflow
clrf REGC0 ;Clear remainder
clrf REGC1
clrf REGC2
clrf REGC3
call slac ;Purge sign bit
movlw D'31' ;Loop counter
movwf MCOUNT
dvloop call slac ;Shift dividend (REGA) msb into remainder (REGC)
movf REGB3,w ;Test if remainder (REGC) >= divisor (REGB)
subwf REGC3,w
skpz
goto dtstgt
movf REGB2,w
subwf REGC2,w
skpz
goto dtstgt
movf REGB1,w
subwf REGC1,w
skpz
goto dtstgt
movf REGB0,w
subwf REGC0,w
dtstgt skpc ;Carry set if remainder >= divisor
goto dremlt
movf REGB0,w ;Subtract divisor (REGB) from remainder (REGC)
subwf REGC0,f
movf REGB1,w
skpc
incfsz REGB1,w
subwf REGC1,f
movf REGB2,w
skpc
incfsz REGB2,w
subwf REGC2,f
movf REGB3,w
skpc
incfsz REGB3,w
subwf REGC3,f
clrc
bsf REGA0,0 ;Set quotient bit
dremlt decfsz MCOUNT,f ;Next
goto dvloop
btfsc MTEMP,0 ;Check result sign
call negatea ;Negative
return
;*** PYÖRISTYS SEURAAVAAN INTEGER LUKUUN, JAKOLASKU***
round clrf MTEMP ;Reset sign flag
call absa ;Make positive
clrc
call slc ;Multiply remainder by 2
movf REGB3,w ;Test if remainder (REGC) >= divisor (REGB)
subwf REGC3,w
skpz
goto rtstgt
movf REGB2,w
subwf REGC2,w
skpz
goto dtstgt
movf REGB1,w
subwf REGC1,w
skpz
goto rtstgt
movf REGB0,w
subwf REGC0,w
rtstgt skpc ;Carry set if remainder >= divisor
goto rremlt
incfsz REGA0,f ;add 1 to quotient
goto rremlt
incfsz REGA1,f
goto rremlt
incfsz REGA2,f
goto rremlt
incf REGA3,f
skpnz
return ;Overflow,return carry set
rremlt btfsc MTEMP,0 ;Restore sign
call negatea
return
;*** 32 BIT NELIÖJUURI***
;sqrt(REGA) -> REGA
;Return carry bit asetettu jos negatiivinen
sqrt rlf REGA3,w ;Trap negative values
skpnc
return
call movac ;Move REGA to REGC
call clrba ;Clear remainder (REGB) and root (REGA)
movlw D'16' ;Loop counter
movwf MCOUNT
sqloop rlf REGC0,f ;Shift two msb's
rlf REGC1,f ;into remainder
rlf REGC2,f
rlf REGC3,f
rlf REGB0,f
rlf REGB1,f
rlf REGB2,f
rlf REGC0,f
rlf REGC1,f
rlf REGC2,f
rlf REGC3,f
rlf REGB0,f
rlf REGB1,f
rlf REGB2,f
setc ;add 1 to root
rlf REGA0,f ;Align root
rlf REGA1,f
rlf REGA2,f
movf REGA2,w ;Test if remdr (REGB) >= root (REGA)
subwf REGB2,w
skpz
goto ststgt
movf REGA1,w
subwf REGB1,w
skpz
goto ststgt
movf REGA0,w
subwf REGB0,w
ststgt skpc ;Carry set if remdr >= root
goto sremlt
movf REGA0,w ;Subtract root (REGA) from remdr (REGB)
subwf REGB0,f
movf REGA1,w
skpc
incfsz REGA1,w
subwf REGB1,f
movf REGA2,w
skpc
incfsz REGA2,w
subwf REGB2,f
bsf REGA0,1 ;Set current root bit
sremlt bcf REGA0,0 ;Clear test bit
decfsz MCOUNT,f ;Next
goto sqloop
clrc
rrf REGA2,f ;Adjust root alignment
rrf REGA1,f
rrf REGA0,f
return
;*** 32 BIT SIGNED BINARY -> DECIMAALIMUUNNOS ***
;REGA -> DIGITS 1 (MSD) TO 10 (LSD) & DSIGN
;DSIGN = 0 if REGA is positive, 1 if negative
;Return carry bit asetettu jos ylivuoto
;Käyttää FSR registeriä
bin2dec clrf MTEMP ;Reset sign flag
call absa ;Make REGA positive
skpnc
return ;Overflow
call clrdig ;Clear all digits
movlw D'32' ;Loop counter
movwf MCOUNT
b2dloop rlf REGA0,f ;Shift msb into carry
rlf REGA1,f
rlf REGA2,f
rlf REGA3,f
movlw DIGIT10
movwf FSR ;Pointer to digits
movlw D'10' ;10 digits to do
movwf DCOUNT
adjlp rlf INDF,f ;Shift digit and carry 1 bit left
movlw D'10'
subwf INDF,w ;Check and adjust for decimal overflow
skpnc
movwf INDF
decf FSR,f ;Next digit
decfsz DCOUNT,f
goto adjlp
decfsz MCOUNT,f ;Next bit
goto b2dloop
btfsc MTEMP,0 ;Check sign
bsf DSIGN,0 ;Negative
clrc
return
;*** 32 BIT SIGNED DECIMAL -> BINARYMUUNNOS ***
;Decimal DIGIT1 thro DIGIT(X) & DSIGN -> REGA
;Set DSIGN = 0 for positive, DSIGN = 1 for negative values
;Most significant digit in DIGIT1
;Enter this routine with digit count in w register
;Return carry bit asetettu jos ylivuoto
;Uses FSR register
dec2bin movwf MTEMP ;Save digit count
movlw D'32' ;Outer bit loop counter
movwf MCOUNT
d2blp1 movlw DIGIT1-1 ;Set up pointer to MSD
movwf FSR
movf MTEMP,w ;Inner digit loop counter
movwf DCOUNT
movlw D'10'
clrc ;Bring in '0' bit into MSD
d2blp2 incf FSR,f
skpnc
addwf INDF,f ;add 10 if '1' bit from prev digit
rrf INDF,f ;Shift out LSB of digit
decfsz DCOUNT,f ;Next L.S. Digit
goto d2blp2
rrf REGA3,f ;Shift in carry from digits
rrf REGA2,f
rrf REGA1,f
rrf REGA0,f
decfsz MCOUNT,f ;Next bit
goto d2blp1
movf INDF,w ;Check for overflow
addlw 0xFF
skpc
rlf REGA3,w
skpnc
return
btfsc DSIGN,0 ;Check result sign
call negatea ;Negative
return
;APUOHJELMIA
;add REGB to REGA (Unsigned)
;Used by add, multiply,
addba movf REGB0,w ;add lo byte
addwf REGA0,f
movf REGB1,w ;add mid-lo byte
skpnc ;No carry_in, so just add
incfsz REGB1,w ;add carry_in to REGB
addwf REGA1,f ;add and propagate carry_out
movf REGB2,w ;add mid-hi byte
skpnc
incfsz REGB2,w
addwf REGA2,f
movf REGB3,w ;add hi byte
skpnc
incfsz REGB3,w
addwf REGA3,f
return
;Siirrä REGA --> REGC
;Käytetään kerto- ja neliöjuurilaskussat
movac movf REGA0,w
movwf REGC0
movf REGA1,w
movwf REGC1
movf REGA2,w
movwf REGC2
movf REGA3,w
movwf REGC3
return
;Clear REGB and REGA
;Used by sqrt
clrba clrf REGB0
clrf REGB1
clrf REGB2
clrf REGB3
;Clear REGA
;Used by multiply, sqrt
clra clrf REGA0
clrf REGA1
clrf REGA2
clrf REGA3
return
;Tarkista REGA merkki ja muunna se negatiivista positiiviseksi
;Käytetään multiply, divide, bin2dec, round
absa rlf REGA3,w
skpc
return ;Positive
;Negate REGA
;Used by absa, multiply, divide, bin2dec, dec2bin, round
negatea movf REGA3,w ;Save sign in w
andlw 0x80
comf REGA0,f ;2's complement
comf REGA1,f
comf REGA2,f
comf REGA3,f
incfsz REGA0,f
goto nega1
incfsz REGA1,f
goto nega1
incfsz REGA2,f
goto nega1
incf REGA3,f
nega1
incf MTEMP,f ;flip sign flag
addwf REGA3,w ;Return carry set if -2147483648
return
;Tarkista onko f REGB negatiivinen ja muunna se positiiviseksi e
;Käytetään multiply, divide
absb rlf REGB3,w
skpc
return ;Positive
;Negate REGB
;Used by absb, subtract, multiply, divide
negateb movf REGB3,w ;Save sign in w
andlw 0x80
comf REGB0,f ;2's complement
comf REGB1,f
comf REGB2,f
comf REGB3,f
incfsz REGB0,f
goto negb1
incfsz REGB1,f
goto negb1
incfsz REGB2,f
goto negb1
incf REGB3,f
negb1
incf MTEMP,f ;flip sign flag
addwf REGB3,w ;Return carry set if -2147483648
return
;Siirrä vasemmalle REGA ja REGC
;Käytetään multiply, divide, round
slac rlf REGA0,f
rlf REGA1,f
rlf REGA2,f
rlf REGA3,f
slc rlf REGC0,f
rlf REGC1,f
rlf REGC2,f
rlf REGC3,f
return
;Set all digits to 0
;Used by bin2dec
clrdig clrf DSIGN
clrf DIGIT1
clrf DIGIT2
clrf DIGIT3
clrf DIGIT4
clrf DIGIT5
clrf DIGIT6
clrf DIGIT7
clrf DIGIT8
clrf DIGIT9
clrf DIGIT10
return
Jukan OH3HYP tekemä matikkarutii
;summausrutiini 24bit pic-prosesorille 03.10.2010 oh3hyp
;
;
; tul_1 ... tul_6 muistipaikkojen alimpiin neljään bittiin jaotellaan toinen
; summattavista 24-bittisistä luvuista ja vastaavasti
; lis_1 ... lis_6 paikkoihin se toinen summattavista luvuista
; alimmat neljä bittiä ykkösiin ja ylimmät neljä kuutosiin.
;
; summa syntyy tul_1 ... tul_7 muistipaikkoihin
;
; tul_7 nollataan ensin ja tässä muistipaikassa tavun bitti b0 nousee ykköseksi
; jos summattavat ovat tarpeeksi suuria
; testaus PIC16F886 ja MPLAB 4.20.2010OH3GDO pieniä korjauksia
lis_1 equ 0x30
lis_2 equ 0x31
lis_3 equ 0x32
lis_4 equ 0x33
lis_5 equ 0x34
lis_6 equ 0x35
tul_1 equ 0x36
tul_2 equ 0x37
tul_3 equ 0x38
tul_4 equ 0x39
tul_5 equ 0x3a
tul_6 equ 0x3b
tul_7 equ 0x3c
;--------
code
summaus
clrf tul_7
movf lis_1 ,w ;otetaan toinen summattava luku w-rekisteriin (alimmat neljä bittiä 24 bittisestä luvusta)
addwf tul_1 ,f ;lisätään ne tulos_tavun sisältöön
btfsc tul_1 ,0x04 ;tutkitaan nousiko viides bitti pienemmästä päästä ykköseksi
goto zx1 ;hyppy zx1:een jos nousi ykköseksi
goto zx2 ;hyppy zx2:een jos pysyi nollana
zx1 bcf tul_1 ,0x04 ;nollataan viides bitti pienemmästä päästä
incf tul_2 ,f ;suurennetaan seuraavan tulos_tavun sisältöä yhdellä eli muistinumero siirretään seuraavaan numeroon
;------
zx2 movf lis_2 ,w
addwf tul_2 ,f
btfsc tul_2 ,0x04
goto zx3
goto zx4
zx3 bcf tul_2 ,0x04
incf tul_3 ,f
;------
zx4 movf lis_3 ,w
addwf tul_3 ,f
btfsc tul_3 ,0x04
goto zx5
goto zx6
zx5 bcf tul_3 ,0x04
incf tul_4 ,f
;------
;------
zx6 movf lis_4 ,w
addwf tul_4 ,f
btfsc tul_4 ,0x04
goto zx7
goto zx8
zx7 bcf tul_4 ,0x04
incf tul_5 ,f
;------
zx8 movf lis_5 ,w
addwf tul_5 ,f
btfsc tul_5 ,0x04
goto zx9
goto zx10
zx9 bcf tul_5 ,0x04
incf tul_6 ,f
;------
zx10 movf lis_6 ,w
addwf tul_6 ,f
btfsc tul_6 ,0x04
goto zx11
goto zx12
zx11 bcf tul_6 ,0x04
incf tul_7 ,f
;------
zx12
END
; loppu
OH3GDO