list p=12c671 include ; some 32-byte "variables" Count equ 20h One equ 24h ; some 64-byte variables Square equ 28h ; some "pointer" registers for argument passing pX equ 70h pY equ 71h pZ equ 72h org 0h ; reset vector reset goto start org 5h start ; this is where execution begins clrf Square ; Square = 0 clrf Square+1 clrf Square+2 clrf Square+3 clrf Square+4 clrf Square+5 clrf Square+6 clrf Square+7 ; clrf Count ; clrf Count+1 ; clrf Count+2 ; clrf Count+3 ; initialize Count to 1000000000 clrf Count movlw H'CA' movwf Count+1 movlw H'9A' movwf Count+2 movlw H'3B' movwf Count+3 clrf One incf One,F clrf One+1 clrf One+2 clrf One+3 loop movlw Count movwf pX movwf pZ movlw One movwf pY call Add32 movlw Count movwf pX movwf pY movlw Square movwf pZ call Mul32 goto loop ; some temporary registers tCarry equ 7Fh tCount equ 7Dh tSum equ 7Ch tX equ 7Bh tY equ 7Ah tZ equ 79h Add32 movf pX,W ; tX = pX movwf tX movf pY,W ; tY = pY movwf tY movf pZ,W ; tZ = pZ movwf tZ movlw 4 ; tCount = 4 movwf tCount clrf tCarry ; tCarry = 0 Add32lp movf tCarry,W ; tSum = tCarry movwf tSum clrf tCarry ; tCarry = 0 movf tX,W ; tSum = tSum + *tX movwf FSR movf INDF,W addwf tSum,F btfsc STATUS,C ; if carry, ++tCarry incf tCarry,F movf tY,W ; tSum = tSum + *tY movwf FSR movf INDF,W addwf tSum,F btfsc STATUS,C ; if carry, ++tCarry incf tCarry,F movf tZ,W ; *tZ = tSum movwf FSR movf tSum,W movwf INDF incf tX,F ; ++tX incf tY,F ; ++tY incf tZ,F ; ++tZ decfsz tCount,F ; --tCount goto Add32lp ; loop if tCount != 0 return ; some temporary registers ; The routine calls Add32. ; Therefore it must not use any of the temporary registers ; the Add32 modifies as its own temporaries uX equ 78h uY equ 77h uZ equ 76h uBCount equ 75h ; These do not need to be preserved across a call to Add32 uSCount equ 7Fh uTemp equ 7Eh Mul32 movf pX,W ; uX = pX movwf uX movf pY,W ; uY = pY movwf uY movf pZ,W ; uZ = pZ movwf uZ movlw D'32' ; uBCount = 32 movwf uBCount ; Initialize the product field ; Set the lower 4 bytes to Y movlw 4 ; uSCount = 4 movwf uSCount MlLp1 movf uY,W ; *uZ = *uY movwf FSR movf INDF,W movwf uTemp movf uZ,W movwf FSR movf uTemp,W movwf INDF incf uY,F ; ++uY incf uZ,F ; ++uZ decfsz uSCount,F goto MlLp1 movf pY,W ; uY = pY movwf uY ; Set the upper 4 bytes to zero movlw 4 ; uSCount = 4 movwf uSCount MlLp2 movf uZ,W ; *uZ = 0 movwf FSR clrf INDF incf uZ,F ; ++uZ decfsz uSCount,F goto MlLp2 movf pZ,W ; uZ = pZ movwf uZ ; set up pX, pY, and pZ for call to add32 ; must set pY to PZ movf pZ,W ; W = pZ addlw 4 ; W = W + 4 movwf pY ; pY = W movwf pZ ; pZ = W ; the *big* outer loop -- do it 32 times MlLp3 movf uZ,W ; test low bit of *uZ movwf FSR rrf INDF,W ; rotate low bit into the C bit btfsc STATUS,C call Add32 ; the inner loop for the shift movlw 8 ; W = 8 movwf uSCount ; uSCount = W addwf uZ,W ; W = uZ+W movwf FSR ; FSR = W bcf STATUS,C ; C bit = 0 MlLp4 decf FSR,F rrf INDF,F decfsz uSCount,F goto MlLp4 decfsz uBCount,F goto MlLp3 ; restore pY and pZ movf uY,W movwf pY movf uZ,W movwf pZ return ; This is really a little silly, end it allows us to create a watch window sq0 equ Square sq1 equ Square+1 sq2 equ Square+2 sq3 equ Square+3 sq4 equ Square+4 sq5 equ Square+5 sq6 equ Square+6 sq7 equ Square+7 ct0 equ Count ct1 equ Count+1 ct2 equ Count+2 ct3 equ Count+3 end