  #include <p16c5x.inc>
	
;********************************************************************
; VARIABLE DEFINITIONS

temp_var        udata
multiplicand	res	1	;multiplicand varible declaration
multiplier	res	1	;multiplier variable declaration
result		res	1	;result variable declaration
count		res	1	;count declaration
resultmsb	res	1	;resultmsb variable declaration
dig0            res	1	;dig0 variable declaration
dig1            res	1	;dig1 variable declaration
dig2            res	1	;dig2 variable declaration
dig3            res	1	;dig3 variable declaration
control         res	1	;control variable declaration
mode            res	1	;mode variable declaration
dividend 	res	1	;dividend variable definition
divisor		res	1	;divisor variable definition
quotient	res	1	;quotient variable definition
remainder	res	1	;remainder variable definition
counter		res 	1	;counter variable definition
dividend_d	res 	1	;dividend_d variable definition
remainder_1	res 	1	;remainder_1 variable definition

;********************************************************************

reset_vector    code   0x1ff         ;processor reset vector
		goto   start

MAIN            CODE   0x000
start	


;read 0 the pin of port A
;set PORTA <1:0> as input
;set PORTA <3:2> as output
;bit pattern is 0011(0x03) 0 for output and 1 for input

                movlw   0x03          ;move literal value to accumulator
                tris   PORTA          ;set PORTA <1:0> as input
                                      ;set PORTA <3:2> as output
;check multiplication or division
;read  PORTA <0>


                movf    PORTA,0       ;move PORT A  to accumulator
                movwf   mode          ;move accumulator to mode
                
;if mode<0> is 0 then division
;if mode<0> is 1 then multiplication
;check mode <0> is 0  if yes call division
                btfss  mode,0          ;skip if mode<0> is one
                goto   division        ;goto nochange
;multiplication
;port reading
                movlw   0x00          ;move literal value to accumulator
                movwf   PORTA         ;move accumulator to PORT A
                   
                movlw   0xff          ;move literal value to accumulator
                tris    PORTB         ;Set PORT B as input
                   
                movf    PORTB,0       ;move PORT B  to accumulator
                movwf   multiplicand  ;move accumulator to multiplicand
                   
                movlw   0xff          ;move literal value to accumulator
                tris    PORTC         ;Set PORT C as input

                movf    PORTC,0       ;move PORT C to accumulator
                movwf   multiplier    ;move accumulator to multiplier 		

                call 	multiplication	;call sub routine muiltiplication
                call    display

                goto     repeat


;*******************************************************************************
division
;port reading

               movlw  0x0          ;move literal value to accumulator
               movwf  PORTA        ;move accumulator to port A

               movlw  0xff         ;move literal value to accumulator
               tris   PORTB        ;Set port B as input

               movf   PORTB,0      ;move port B to accumulator
               movwf  dividend     ;move accumulator to dividend

               movlw  0xff         ;move literal value to accumulator
               TRIS   PORTC        ;Set PORT C as input

               movf   PORTC,0      ;move PORT C to accumulator
               movwf  divisor      ;move accumulator to divisor

               movlw  0x5	   ;move literal value to accumulator
               movwf  counter	   ;move accumulator to counter for initialize
	       clrw		   ;clear accumulator
	       movwf  quotient	   ;move accumulator to quotient
	       movwf  remainder	   ;move accumulator to remainder
	
loop1

               bcf    STATUS,0	   ;clear carry
               movf   dividend,0   ;move dividend to accumulator
               movwf  dividend_d   ;move accumulator to dividend_d
		
;shift right it by 4

               rrf    dividend_d,1 ;right shift
               rrf    dividend_d,1 ;right shift
	       rrf    dividend_d,1 ;right shift
	       rrf    dividend_d,1 ;right shift

;mask msb  by 0
	       movlw  0x0f	   ;move literal value to accumulator
	       andwf  dividend_d,1 ;AND accumulator with the dummy dividend
                                   ;inorder to mask msb of dummy dividend.

;Comparison
	       movf   divisor,0	   ;move divisor to accumulator
	       subwf  dividend_d,1 ;subtract accumulator with the dividend_d
	       btfsc  STATUS,0	   ;skip next statement if result is negative
	       call   subtraction
	       rlf    quotient,1   ;shift left the quotient

	       movf   dividend,0   ;move dividend to accumulator
	       movwf  dividend_d   ;move dividend to its dummy

	       bcf    STATUS,0	   ;clear carry
	       rlf    dividend,1   ;shift left the dividend

	       decfsz counter,1	   ;decrement and skip if zero
	       goto   loop1	   ;check counter


	       movf   dividend_d,0 ;move dividend_d to accumulator before shifting
	       movwf  remainder	   ;move dividend_d to remainder
	       bcf    STATUS,0	   ;clear carry
	       rrf    remainder,1  ;right shift
	       rrf    remainder,1  ;right shift
	       rrf    remainder,1  ;right shift
	       rrf    remainder,1  ;right shift

;move remainder to result
;move quotient to resultmsb
               movf   remainder,0  ;move remainder to accumulator
	       movwf  result	   ;move accumulator to remainder
	       
               movf   quotient,0  ;move quotient to accumulator
	       movwf  resultmsb	   ;move accumulator to resultmsb
	       
               call   display	

               goto    repeat			;infinite loop

subtraction
                movlw   0x0f			;move literal value to accumulator
		andwf   dividend,1 	        ;AND accumulator with the dividend
                                                ;inorder to mask msb of dividend.

		bcf     STATUS,0	        ;clear carry
		rlf     dividend_d,1            ;left shift
		rlf     dividend_d,1            ;left shift
		rlf     dividend_d,1            ;left shift
		rlf     dividend_d,1            ;left shift

		movlw   0xf0			;move literal value to accumulator
		andwf   dividend_d,1 	        ;AND accumulator with the dummy dividend
                                                ; inorder to mask lsb of dummy dividend.

		movf    dividend_d,0		;move dividend_d to accumulator
		
		addwf   dividend,1		;add accumulator with the dividend
                                                ;and store the result in divident			
			
		bsf     STATUS,0		;set carry
		
		clrw				;clear accumulator
		tris    PORTB		        ;set port B as output port
		movf    dividend,0		;move dividend to accumulator
		movwf   PORTB		        ;write the result to port B	

		retlw   0



;*****************************************************************************
repeat            goto    repeat	;infinite loop
;****************************************************************************
multiplication

                  clrw 			;clear accumulator
		  movwf   result	;move accumulator value to result
		  movwf   resultmsb	;move accumulator value to result msb
		  incf 	  multiplier,1	;increment multiplier by 1 and store in multiplier
		  movf    multiplier,0	;move multiplier value to accumulator
		  movwf	  count		;move accumulator value to count
loop
		  decfsz  count,1	;decrement count and test is zero if yes then skip
		  goto    addition
		  retlw   0		;return subroutine

addition
		  movf 	  multiplicand,0;move multiplicand to accumulator
		  addwf   result,1	;add multiplicand to result and stored in result
	
		  btfsc   STATUS,0	;if carry is zero then skip
		  incf    resultmsb,1   ;if carry then increment msb by 1
		  clrw                  ;clear accumulator

		  goto   loop 	

 ;*******************************************************************************
 

;******************************************************************************
display                                     		

;hpdl 1414 implementation

;74245 as output mode
              	 movlw   0xf          ;move literal value to accumulator
                 movwf   PORTA        ;move accumulator TO port A

                 movlw   0x00         ;move literal value to accumulator
                 tris    PORTB        ;Set PORT B as output

                 movlw   0x00         ;move literal value to accumulator
                 tris    PORTC        ;Set PORT C as output

;display  of DIG0

;Set 74245 in output mode

;separation of zeroth  digit

                  movlw  0x0f         ;move literal value to accumulator
                  andwf  result,0     ;AND result with accumulator and
                                      ;output in accumulator
                  movwf  dig0         ;move accumulator to dig0

;check digit is greater than 9

                  movlw  0x09         ;move literal value to accumulator
                  subwf  dig0,0       ;subtract 9 from dig0 and result in accumulator

                  btfss  STATUS, 0    ;skip if carry flag  is 1
                  goto   nochange     ;goto nochange

                  btfsc  STATUS,2     ;skip if zero flag is zero
                                      ;ie result is non zero
                  goto   nochange     ;goto nochange

                  movlw  0x09         ;move literal value to accumulator
                  subwf  dig0,1       ;subtract 9 from dig0 and result in dig0

                  movlw  0x13         ;move literal value to accumulator
                  movwf  control      ;move control to accumulator

                  goto   porting0     ;goto porting 0

nochange          movlw  0x0f         ;move literal value to accumulator
                  movwf  control      ;move control to accumulator

porting0          movf   dig0,0       ;move dig0 value to accumulator
                  movwf  PORTB        ;move accumulator to portB

                  movf   control,0    ;move control value to accumulator
                  movwf  PORTC        ;move accumulator to port C

                  movlw  0xff         ;move literal value to accumulator
                  movwf  control      ;move control to accumulator

                  movf   control,0    ;move control value to accumulator
                  movwf  PORTC        ;move accumulator to port C



;zeroth  digit complete

;first  digit

;separation of  first  digit

                  movlw  0xf0          ;move literal value to accumulator
                  andwf  result,0      ;AND result with accumulator and output in accumulator
                  movwf  dig1          ;move accumulator to dig1
                  swapf  dig1,1        ;swap and result in dig1

;check digit is greater than 9

                  movlw  0x09         ;move literal value to accumulator
                  subwf  dig1,0       ;subtract 9 from dig1 and result in accumulator

                  btfss  STATUS, 0    ;skip if carry flag  is 1
                  goto   nochange1    ;goto nochange1

                  btfsc  STATUS,2     ;skip if zero flag is zero
                                      ;ie result is non zero
                  goto   nochange1    ;goto nochange1

                  movlw  0x09         ;move literal value to accumulator
                  subwf  dig1,1       ;subtract 9 from dig1 and result in dig1

                  movlw  0x12         ;move literal value to accumulator
                  movwf  control      ;move control to accumulator

                  goto   porting1     ;goto porting 1

nochange1         movlw  0x0e         ;move literal value to accumulator
                  movwf  control      ;move control to accumulator

porting1          movf   dig1,0       ;move dig1 value to accumulator
                  movwf  PORTB        ;move accumulator to portB

                  movf   control,0    ;move control value to accumulator
                  movwf  PORTC        ;move accumulator to port C

                  movlw  0xff         ;move literal value to accumulator
                  movwf  control      ;move control to accumulator

                  movf   control,0    ;move control value to accumulator
                  movwf  PORTC        ;move accumulator to port C


;separation of second  digit

                  movlw   0x0f         ;move literal value to accumulator
                  andwf   resultmsb,0  ;AND resultmsb with accumulator and output in accumulator
                  movwf   dig2         ;move accumulator to dig2

;check digit is greater than 9

                  movlw   0x09         ;move literal value to accumulator
                  subwf   dig2,0       ;subtract 9 from dig2 and result in accumulator

                  btfss   STATUS, 0    ;skip if carry flag  is 1
                  goto    nochange2    ;goto nochange2

                  btfsc   STATUS,2     ;skip if zero flag is zero
                                       ;ie result is non zero
                  goto    nochange2    ;goto nochange2

                  movlw   0x09         ;move literal value to accumulator
                  subwf   dig2,1       ;subtract 9 from dig2 and result in dig2

                  movlw   0x11         ;move literal value to accumulator
                  movwf   control      ;move control to accumulator

                  goto    porting2     ;goto porting 2

nochange2         movlw   0x0d         ;move literal value to accumulator
                  movwf   control      ;move control to accumulator

porting2          movf    dig2,0       ;move dig2 value to accumulator
                  movwf   PORTB        ;move accumulator to portB

                  movf    control,0    ;move control value to accumulator
                  movwf   PORTC        ;move accumulator to port C

                  movlw   0xff         ;move literal value to accumulator
                  movwf   control      ;move control to accumulator

                  movf    control,0    ;move control value to accumulator
                  movwf   PORTC        ;move accumulator to port C


;second digit   complete

;third digit

;separation of  third  digit

                  movlw   0xf0          ;move literal value to accumulator
                  andwf   resultmsb,0   ;AND resultmsb with accumulator and output in accumulator
                  movwf   dig3          ;move accumulator to dig3
                  swapf   dig3,1        ;swap and result in dig3

;check digit is grater than 9

                  movlw    0x09         ;move literal value to accumulator
                  subwf    dig3,0       ;subtract 9 from dig3 and result in accumulator

                  btfss    STATUS, 0    ;skip if carry flag  is 1
                  goto     nochange3    ;goto nochange3

                  btfsc    STATUS,2     ;skip if zero flag is zero
                                        ;ie result is non zero
                  goto     nochange3    ;goto nochange3

                  movlw    0x09         ;move literal value to accumulator
                  subwf    dig3,1       ;subtract 9 from dig3 and result in dig3

                  movlw    0x10          ;move literal value to accumulator
                  movwf    control       ;move control to accumulator

                  goto     porting3      ;goto porting 3

nochange3         movlw    0x0c          ;move literal value to accumulator
                  movwf    control       ;move control to accumulator

porting3          movf     dig3,0        ;move dig3 value to accumulator
                  movwf    PORTB         ;move accumulator to portB

                  movf     control,0     ;move control value to accumulator
                  movwf    PORTC         ;move accumulator to port C

                  movlw    0xff          ;move literal value to accumulator
                  movwf    control       ;move control to accumulator

                  movf     control,0     ;move control value to accumulator
                  movwf    PORTC         ;move accumulator to port C
;testing
                  ;goto repeat
                  retlw    0
;testing
 ;*****************************************************************                    	
	
                  end                   ; directive 'end of program'












