;-------------------------------;
;     MATEMATIKA PIC (24B)	;
;-------------------------------;
;slovak@post.cz	      )S(01.2007;
;www.s-o.webnode.cz		;
;-------------------------------;
; dělení, násobení,		;
; odečítání, sčítání,		;
; násobení konstantou		;
;===============================;
; Matematické podprogramy	;
;pracují pouze s celými čísly.	;
; POZOR nemají ochranu proti	;
;přetečení mimo rozsah !!!	;
;-------------------------------;
; Rozsah 24 bit.		;
;MAX = 16777215 = 0xFFFFFF	;
;MIN = 0	= 0x000000	;
;-------------------------------;
; Rozsah 23+1 bit.		;
;MAX =  8388607 = 0x7FFFFF	;
;MIN = -8388608 = 0x800000	;
;(MSB=0=kladné, 1=zaporné)	;
;-------------------------------;


;*******************************;
; Testovací program v MPLABu	;
;*******************************;
;Postup:
;1. Zadej hodnoty A a B (C)
;2. Vyber jedenu funkci
;3. Ulož (Ctrl S)
;4. Zkompiluj (Alt F10)
;5. Processor Reset (F6)
;6. Krokuj (F8), až do návěstí Etest
;7. Výsledek = otevři View/File Registers,
;   přepni na zobrazení Symbolic a najdi
;   řádky C1, C2, C3
;--------------------------------
 LIST P=16F628A, R=DEC		;direktivy překladače
 include<p16f628a.inc>		;definice názvů registrů

;definice matematických proměnných
 cblock	0x20
A1				;LByte (dolní)
A2				;MByte (střední)
A3				;HByte (horní)
B1				;
B2				;
B3				;
C1				;
C2				;
C3				;
D1				;
D2				;
D3				;
X1				;
X2				;
FL				;Flag
 endc

#define	Azn	FL,7		;znaménko A, 0=kladné 1=záporné
#define	Bzn	FL,6		;znaménko B, 0=kladné 1=záporné
;--------------------------------
	ORG	0
	GOTO	Start
	ORG	4
	RETFIE
Start
;zadej A
	MOVLW	0x20		;A=7428640=0x715A20
	MOVWF	A1		;
	MOVLW	0x5A		;
	MOVWF	A2		;
	MOVLW	0x71		;(MSB=0)
	MOVWF	A3		;
;zadej B
	MOVLW	0x0C		;B=-500=0xFFFE0C
	MOVWF	B1		;
	MOVLW	0xFE		;
	MOVWF	B2		;
	MOVLW	0xFF		;(MSB=1)
	MOVWF	B3		;
;zadej C
;	MOVLW	0xF4		;B=500=0x0001F4
;	MOVWF	C1		;
;	MOVLW	0x01		;
;	MOVWF	C2		;
;	MOVLW	0x00		;(MSB=0)
;	MOVWF	C3		;

;vyber jedenu funkci
;	CALL	LOMENO24	;A/B=C (pouze kladná čísla)
	CALL	LOMENO		;A/B=C
;	CALL	KRAT24		;A*B=C (pouze kladná čísla)
;	CALL	KRAT		;A*B=C
;	CALL	MINUS		;A-B=C
;	CALL	PLUS		;A+C=C
;násobení konstantou
;	CALL	x8192		;A*8192=A (vstup A=MAX=2047, MIN=0)
;	CALL	x2128		;C*2128=A (vstup C=MAX=7884, MIN=0)

Etest	GOTO	Etest		;konec testovacího programu

;-------------------------------;
;   Matematicke podprogramy	;
;-------------------------------;
;slovak@post.cz	      )S(12.2004;
;-------------------------------;
; A1,2,3 / B1,2,3 = C1,2,3
;24Bit, pouze kladna cisla
;SZ=1=deleni nulou (B1,2,3=0)
;B se nezmeni, v A bude zbytek
;pouziva D1,2,3; X1
LOMENO24
;test B na nulu; sZ=1=ANO
	MOVF	B1,F
	BTFSC	STATUS,Z	;nenulove?
	MOVF	B2,F
	BTFSC	STATUS,Z	;nenulove?
	MOVF	B3,F
	BTFSC	STATUS,Z	;nenulove?
	RETURN			;B1,2,3=0
;priprava pro deleni
LOM24	MOVF	A1,W		;A do D
	MOVWF	D1		;
	MOVF	A2,W		;
	MOVWF	D2		;
	MOVF	A3,W		;
	MOVWF	D3		;
	CLRF	A1		;nulovat
	CLRF	A2		;
	CLRF	A3		;
	MOVLW	24		;pocet bitu
	MOVWF	X1		;
	BCF	STATUS,C	;SC=0
;deleni
LDalsi	CALL	x2M		;D,A posun vlevo, A-B=C
	BTFSS	STATUS,C	;kladny vysledek?
	GOTO	LZapor		;NE
;LKlad
	MOVWF	A3		;C do A
	MOVF	C2,W		;
	MOVWF	A2		;
	MOVF	C1,W		;
	MOVWF	A1		;

LZapor	DECFSZ	X1,F		;-1=0?
	GOTO	LDalsi		;jeste neni konec
;vysledek
	RLF	D1,W		;posledni x2
	MOVWF	C1		; a W do C
	RLF	D2,W		;
	MOVWF	C2		;
	RLF	D3,W		;
	MOVWF	C3		;

	BCF	STATUS,Z	;SZ=0
	RETURN

;--------------------------------
; A1,2,3 / B1,2,3 = C1,2,3
;23Bit; MSB=0=kladne, 1=zaporne
;SZ=1=deleni nulou (B1,2,3=0)
;B se nezmeni, v A bude zbytek
;pouziva D1,2,3; X1; FL,Azn,Bzn
LOMENO
;test B na nulu; SZ=1=ANO
	MOVF	B1,F
	BTFSC	STATUS,Z	;nenulove?
	MOVF	B2,F
	BTFSC	STATUS,Z	;nenulove?
	MOVF	B3,F
	BTFSC	STATUS,Z	;nenulove?
	RETURN			;B1,2,3=0
;test A=zaporne
	BCF	Azn		;=0
	BTFSC	A3,7		;MSB=1?
	CALL	ZZA		;zmena znamenka A1,2,3
;test B=zaporne
	BCF	Bzn		;=0
	BTFSC	B3,7		;MSB=0?
	CALL	ZZB		;zmena znamenka B1,2,3
;vypocet
	CALL	LOM24
;vratit B
	BTFSC	Bzn		;=0?
	CALL	ZZB
;znamenko C, test Azn = Bzn
	BTFSC	Azn		;=0?
	GOTO	$+4		;NE
	BTFSC	Bzn		;=0?
	GOTO	$+3		;NE
	GOTO	$+3		;Azn = Bzn = 0
	BTFSS	Bzn		;=1?
	CALL	ZZC		;NE, zmena znamenka C1,2,3

	BCF	STATUS,Z	;SZ=0
	RETURN

;................................
; D1,2,3 A1,2,3 * 2 a Minus
x2M	RLF	D1,F		;posuv vlevo
	RLF	D2,F		;
	RLF	D3,F		;
	RLF	A1,F		;
	RLF	A2,F		;
	RLF	A3,F		;
				;pokracuje MINUS
;--------------------------------
; A1,2,3 - B1,2,3 = C1,2,3
;SC=0=zaporny vysledek
;A,B se nezmeni
MINUS	MOVF	B1,W		;W=B1
	SUBWF	A1,W		;A1-B1=W
	MOVWF	C1		;C1=W=vysledek1
	CLRW			;W=0
	BTFSS	STATUS,C	;SUB kladne?
	MOVLW	1		;W=1
	ADDWF	B2,W		;B2+W=W
	CLRF	C3		;C3=0
	BTFSC	STATUS,C	;ADD nepreteklo?
	BSF	C3,0		;C3=1
	SUBWF	A2,W		;A2-W=W
	MOVWF	C2		;C2=w=vysledek2
	MOVF	C3,W		;W=C3
	BTFSS	STATUS,C	;SUB kladne?
	MOVLW	1		;W=1
	ADDWF	B3,W		;B3+W=W
	CLRF	C3		;C3=0
	BTFSC	STATUS,C	;ADD nepreteklo?
	BSF	C3,0		;C3=1
	SUBWF	A3,W		;A3-W=W
	BTFSC	C3,0		;C3=0?
	BCF	STATUS,C	;SC=0
	MOVWF	C3		;C3=W=vysledek3
	RETURN

;--------------------------------
; A1,2,3 + C1,2,3 = C1,2,3
;A se nemeni
PLUS	MOVF	A1,W
	ADDWF	C1,F		;A1+C1=C1
	BTFSS	STATUS,C	;preteklo?
	GOTO	$+4
	INCFSZ	C2,F		;+1=0?
	GOTO	$+2
	INCF	C3,F		;+1
	MOVF	A2,W
	ADDWF	C2,F		;A2+C2=C2
	BTFSC	STATUS,C	;nepreteklo?
	INCF	C3,F		;+1
	MOVF	A3,W
	ADDWF	C3,F		;A3+C3=C3
	RETURN

;--------------------------------
; A1,2,3 * B1,2,3 = C1,2,3
;24Bit, pouze kladna cisla
;A, B se nezmeni
;pouziva D1,2,3; X1; X2
KRAT24
;schovat A do D
	MOVF	A1,W		;A do D
	MOVWF	D1		;
	MOVF	A2,W		;
	MOVWF	D2		;
	MOVF	A3,W		;
	MOVWF	D3		;
;priprava
	CLRF	C1		;nulovat
	CLRF	C2		;
	CLRF	C3		;
	BCF	STATUS,C	;
	MOVLW	25		;pocet bitu+1
	MOVWF	X1		;
;hledat jednicku
	RRF	B3,F		;posuv vpravo
	RRF	B2,F		;
	RRF	B1,F		;
	MOVF	STATUS,W	;ulozit
	MOVWF	X2		; SC
	BTFSC	STATUS,C	;=0?
;A+C=C
	CALL	PLUS		;jen pri SC=1
;A*2
	RLF	A1,F		;posuv vlevo
	RLF	A2,F		;
	RLF	A3,F		;

	MOVF	X2,W		;obnovit
	MOVWF	STATUS		; SC

	DECFSZ	X1,F		;-1=0?
	GOTO	$-13		;NE
;obnovit A z D
	MOVF	D1,W		;D do A
	MOVWF	A1		;
	MOVF	D2,W		;
	MOVWF	A2		;
	MOVF	D3,W		;
	MOVWF	A3		;
	RETURN		

;--------------------------------
; A1,2,3 * B1,2,3 = C1,2,3
;23Bit, MSB=0=kladne, 1=zaporne
;A, B se nezmeni
;pouziva D1,2,3; X1; X2
KRAT
;test A=zaporne
	BCF	Azn
	BTFSC	A3,7		;=0?
	CALL	ZZA		;zmena znamenka A
;test B=zaporne
	BCF	Bzn
	BTFSC	B3,7		;=0?
	CALL	ZZB		;zmena znamenka B
;vypocet
	CALL	KRAT24		;A*B=C
;znamenko A
	BTFSC	Azn		;=0?
	CALL	ZZA
;znamenko B
	BTFSC	Bzn		;=0?
	CALL	ZZB
;znamenko C, test Azn = Bzn
	BTFSC	Azn		;=0?
	GOTO	$+4		;NE
	BTFSC	Bzn		;=0?
	GOTO	$+3		;NE
	GOTO	$+3		;Azn = Bzn = 0
	BTFSS	Bzn		;=1?
	CALL	ZZC		;NE, zmena znamenka C1,2,3

	BCF	STATUS,Z	;SZ=0
	RETURN

;--------------------------------
;zmena znamenka A1,2,3
ZZA	BSF	Azn		;=1
	COMF	A1,F
	COMF	A2,F
	COMF	A3,F
	INCFSZ	A1,F		;+1,=0?
	RETURN
	INCFSZ	A2,F		;+1,=0?
	RETURN
	INCF	A3,F		;+1
	RETURN

;--------------------------------
;zmena znamenka B1,2,3
ZZB	BSF	Bzn		;=1
	COMF	B1,F
	COMF	B2,F
	COMF	B3,F
	INCFSZ	B1,F		;+1,=0?
	RETURN
	INCFSZ	B2,F		;+1,=0?
	RETURN
	INCF	B3,F		;+1
	RETURN

;--------------------------------
;zmena znamenka C1,2,3
ZZC	COMF	C1,F
	COMF	C2,F
	COMF	C3,F
	INCFSZ	C1,F		;+1,=0?
	RETURN
	INCFSZ	C2,F		;+1,=0?
	RETURN
	INCF	C3,F		;+1
	RETURN

;================================
;násobení konstantou 8192
;pro posunutí desetiné čárky
; A1,2 * 8192 = A1,2,3
x8192	SWAPF	A2,W
	ANDLW	0xF0
	MOVWF	A3
	SWAPF	A1,W
	ANDLW	0x0F
	IORWF	A3,F
	SWAPF	A1,W
	ANDLW	0xF0
	MOVWF	A2
	CLRF	A1
	BCF	STATUS,C
	RLF	A2,F
	RLF	A3,F
	RETURN

;--------------------------------
;násobení konstantou 2128
;pro výpočet teploty ze snímače SMT160-30
; C1,2 * 2128 = A1,2,3
x2128	CLRF	C3		
	CLRF	A1		;A=0
	CLRF	A2		;
	CLRF	A3		;
				;16+64+2048=2128
	MOVLW	4		;4x
	CALL	x2W		; posuv vlevo C =A
	MOVLW	2		;2x
	CALL	x2W		; posuv vlevo C =A
	MOVLW	5		;5x
;	CALL	x2W		; posuv vlevo C =A
;	RETURN

;C1,2,3 * 2^W = C1,2,3 + A1,2,3 = A1,2,3
x2W	MOVWF	X2		;kolikrát
	BCF	STATUS,C	;SC=0
	RLF	C1,F		;posuv vlevo
	RLF	C2,F		;
	RLF	C3,F		;
	DECFSZ	X2,F		;-1=0?
	GOTO	$-5		;znova

CPA	MOVF	C1,W		;součet
	ADDWF	A1,F		;C1+A1=A1
	BTFSS	STATUS,C	;přeteklo?
	GOTO	$+4
	INCFSZ	A2,F		;+1=0?
	GOTO	$+2
	INCF	A3,F		;+1
	MOVF	C2,W
	ADDWF	A2,F		;C2+A2=A2
	BTFSC	STATUS,C	;nepřeteklo?
	INCF	A3,F		;+1
	MOVF	C3,W
	ADDWF	A3,F		;C3+A3=A3
	RETURN

;--------------------------------
	END

