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

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License