	nolist
;*********************************************************************
;
; letzte Änderung 23.02.2000
;
; Alle Routinen gehen davon aus, daß das niederwertigste Byte zuerst
; kommt ( Low-Byte, High-Byte ) und der entsprechende Platz im RAM
; reserviert ist z.B. ExtS16
;
;*********************************************************************


;************************************************
; Diese Macro's werden für den PIC16C73A benutzt
;************************************************

page1	equ 0x800

gotox	macro adr

	errorlevel -306

	if ((adr & page1) == page1)
	  bsf pclath,3
	else
	  bcf pclath,3
	endif

	goto adr

	errorlevel +306

	endm

callx	macro adr

	errorlevel -306

	if ((adr & page1) == page1)
	  bsf pclath,3
	else
	  bcf pclath,3
	endif

	call adr

	if (($ & page1) == page1)
	  bsf pclath,3
	else
	  bcf pclath,3
	endif

	errorlevel +306

	endm

;************************************************
; ab hier für alle
;************************************************

;Jump Bit Set
jbs	macro ram,bit,adr
	btfsc ram,bit
	goto adr
	endm

;Jump Bit Clear
jbc	macro ram,bit,adr
	btfss ram,bit
	goto adr
	endm

;Jump Zero
jz 	macro adr
	btfsc status,zero
	goto adr
	endm

;Jump Not Zero
jnz	macro adr
	btfss status,zero
	goto adr
	endm

;Jump Carry Clear
jcc	macro adr
	btfss status,carry
	goto adr
	endm

;Jump Carry Set
jcs	macro adr
	btfsc status,carry
	goto adr
	endm

;************************************************
; Diese Macro's werden benutzt nach einem CMP Befehl
;************************************************

; Springe wenn variable > konstante (greater)

jg	macro adr
	local jg1
	jz jg1
	jcs adr
jg1
 	endm

; Springe wenn variable >= konstante (greater or equal)

jge	macro adr
	jcs adr
	endm

; Springe wenn variable < konstante (less)

jl	macro adr
	jcc adr
	endm

; Springe wenn variable <= konstante (less or equal)

jle	macro adr
 	jz adr
 	jcc adr
 	endm

; Springe wenn variable = konstante (equal)

je	macro adr
	jz adr
	endm

; Springe wenn variable <> konstante ( not equal)

jne	macro adr
	jnz adr
	endm

;************************************************
; Diverse
;************************************************

Bank0	macro
	bcf status,rp0
	errorlevel +302
	endm

Bank1	macro
	bsf status,rp0
	errorlevel -302
	endm

push	macro
	movwf wsav			
	swapf status,w	; Swap verändert das STATUS-Register nicht
	clrf status
	movwf ssav
	endm

pop	macro
	swapf ssav,w
	movwf status
	swapf wsav,f
	swapf wsav,w
	retfie
	endm

clc	macro
	bcf status,carry
	endm

sec	macro
	bsf status,carry
	endm

;************************************************
; Duo-LED
;************************************************

LEDROT	macro
	BCF LEDK
	BSF LEDA
	endm

LEDGRUEN	macro
	BSF LEDK
	BCF LEDA
	endm

LEDAUS	macro
	BCF LEDK
	BCF LEDA
	endm

;************************************************
; 16 Bit rrf
;************************************************

rrf16	macro op1

	rrf op1+1,f
	rrf op1+0,f

	endm

;************************************************
; 24 Bit rrf
;************************************************

rrf24	macro op1

	rrf op1+2,f
	rrf op1+1,f
	rrf op1+0,f

	endm

;************************************************
; 32 Bit rrf
;************************************************

rrf32	macro op1

	rrf op1+3,f
	rrf op1+2,f
	rrf op1+1,f
	rrf op1+0,f

	endm


;************************************************
; 64 Bit rrf
;************************************************

rrf64	macro op1

	rrf op1+7,f
	rrf op1+6,f
	rrf op1+5,f
	rrf op1+4,f
	rrf op1+3,f
	rrf op1+2,f
	rrf op1+1,f
	rrf op1+0,f

	endm

;************************************************
; 16 Bit rlf
;************************************************

rlf16	macro op1

	rlf op1+0,f
	rlf op1+1,f

	endm

;************************************************
; 24 Bit rlf
;************************************************

rlf24	macro op1

	rlf op1+0,f
	rlf op1+1,f
	rlf op1+2,f

	endm

;************************************************
; 32 Bit rlf
;************************************************

rlf32	macro op1

	rlf op1+0,f
	rlf op1+1,f
	rlf op1+2,f
	rlf op1+3,f

	endm

;************************************************
; 64 Bit rlf
;************************************************

rlf64	macro op1

	rlf op1+0,f
	rlf op1+1,f
	rlf op1+2,f
	rlf op1+3,f
	rlf op1+4,f
	rlf op1+5,f
	rlf op1+6,f
	rlf op1+7,f

	endm

;************************************************
; Negation (2er Komlement)
; op1 = -op1
;************************************************

;************************************************
; 8 Bit negation
;************************************************

neg8	macro op1

	comf op1,f
	incf op1,f

	endm

;************************************************
; 16 Bit Negation
;************************************************

neg16	macro op1

	local ok

	comf op1,f
	comf op1+1,f

	incfsz op1,f
	goto ok
	incf op1+1,f
ok
	endm

;************************************************
; 24 Bit Negation
;************************************************

neg24	macro op1

	local ok

	comf op1,f
	comf op1+1,f
	comf op1+2,f

	incfsz op1,f
	goto ok
	incfsz op1+1,f
	goto ok
	incf op1+2,f
ok
	endm

;************************************************
; 32 Bit Negation
;************************************************

neg32	macro op1

	local ok

	comf op1,f
	comf op1+1,f
	comf op1+2,f
	comf op1+3,f

	incfsz op1,f
	goto ok
	incfsz op1+1,f
	goto ok
	incfsz op1+2,f
	goto ok
	incf op1+3,f
ok
	endm

;************************************************
; 64 Bit Negation
;************************************************

neg64	macro op1

	local ok

	comf op1+0,f
	comf op1+1,f
	comf op1+2,f
	comf op1+3,f
	comf op1+4,f
	comf op1+5,f
	comf op1+6,f
	comf op1+7,f

	incfsz op1+0,f
	goto ok
	incfsz op1+1,f
	goto ok
	incfsz op1+2,f
	goto ok
	incfsz op1+3,f
	goto ok
	incfsz op1+4,f
	goto ok
	incfsz op1+5,f
	goto ok
	incfsz op1+6,f
	goto ok
	incf op1+7,f
ok
	endm

;************************************************
; 16 Bit clrf
; op1 = 0
;************************************************

clrf16	macro op1

	clrf op1
	clrf op1+1

	endm

;************************************************
; 24 Bit clrf
; op1 = 0
;************************************************

clrf24	macro op1

	clrf op1
	clrf op1+1
	clrf op1+2

	endm

;************************************************
; 32 Bit clrf
; op1 = 0
;************************************************

clrf32	macro op1

	clrf op1
	clrf op1+1
	clrf op1+2
	clrf op1+3

	endm

;************************************************
; 64 Bit clrf
; op1 = 0
;************************************************

clrf64	macro op1

	clrf op1
	clrf op1+1
	clrf op1+2
	clrf op1+3
	clrf op1+4
	clrf op1+5
	clrf op1+6
	clrf op1+7

	endm

;************************************************
; op1 auf 16-Bit erweitern
; op1 ist eine 8-Bit Variable ohne Vorzeichen
; ExtU16
; 
;************************************************

extu16	macro op1

	clrf op1+1

	endm

;************************************************
; op1 vorzeichenrichtig auf 16-Bit erweitern
; op1 ist eine 8-Bit Variable mit Vorzeichen
; ExtS16
;
;************************************************

exts16	macro op1

	clrf op1+1
	btfsc op1,7	; negativ ?
	decf op1+1,f	; ja

	endm

;************************************************
; op1 auf 24-Bit erweitern
; op1 ist eine 16-Bit Variable ohne Vorzeichen
; ExtU24
; 
;************************************************

extu24	macro op1

	clrf op1+2

	endm

;************************************************
; op1 vorzeichenrichtig auf 32-Bit erweitern
; op1 ist eine 16-Bit Variable mit Vorzeichen
; ExtS24
;
;************************************************

exts24	macro op1

	movlw 0
	btfsc op1+1,7	; negativ ?
	movlw 255	; ja
	movwf op1+2

	endm

;************************************************
; op1 auf 32-Bit erweitern
; op1 ist eine 16-Bit Variable ohne Vorzeichen
; ExtU32
; 
;************************************************

extu32	macro op1

	clrf op1+2
	clrf op1+3

	endm

;************************************************
; op1 vorzeichenrichtig auf 32-Bit erweitern
; op1 ist eine 16-Bit Variable mit Vorzeichen
; ExtS32
;
;************************************************

exts32	macro op1

	movlw 0
	btfsc op1+1,7	; negativ ?
	movlw 255	; ja
	movwf op1+2
	movwf op1+3

	endm

;************************************************
; 8 Bit move literal
; op1 = konst
;************************************************

movl8	macro op1,konst

	movlw (konst & H'FF')
	movwf op1

	endm

;************************************************
; 16 Bit move literal
; op1 = Konst
;************************************************

movl16	macro op1,konst

	movlw (konst & H'FF')
	movwf op1
	movlw (konst >> 8) & H'FF'
	movwf op1+1

	endm

;************************************************
; 32 Bit move literal
; op1 = Konst
;************************************************

movl32	macro op1,konst

	movlw konst & H'FF'
	movwf op1
	movlw (konst >> 8) & H'FF'
	movwf op1+1
	movlw (konst >> 16) & H'FF'
	movwf op1+2
	movlw (konst >> 24) & H'FF'
	movwf op1+3

	endm

;************************************************
; 24 Bit move literal
; op1 = Konst
;************************************************

movl24	macro op1,konst

	movlw konst & H'FF'
	movwf op1
	movlw (konst >> 8) & H'FF'
	movwf op1+1
	movlw (konst >> 16) & H'FF'
	movwf op1+2

	endm

;************************************************
; 8 Bit move
; op1 = op2
;************************************************

mov8	macro op1,op2

	movfw op2
	movwf op1

	endm

;************************************************
; 16 Bit move
; op1 = op2
;************************************************

mov16	macro op1,op2

	movfw op2
	movwf op1
	movfw op2+1
	movwf op1+1

	endm

;************************************************
; 24 Bit move
; op1 = op2
;************************************************

mov24	macro op1,op2

	movfw op2
	movwf op1
	movfw op2+1
	movwf op1+1
	movfw op2+2
	movwf op1+2

	endm

;************************************************
; 32 Bit move
; op1 = op2
;************************************************

mov32	macro op1,op2

	movfw op2
	movwf op1
	movfw op2+1
	movwf op1+1
	movfw op2+2
	movwf op1+2
	movfw op2+3
	movwf op1+3

	endm

;************************************************
; 8 Bit Addition mit Konstante
; OP1 = OP1 + Konst
;************************************************

addl8	macro op1,konst	; op1+konst -> op1

	movlw konst & H'FF'
	addwf op1,f

	endm

;************************************************
; 16 Bit Addition mit Konstante
; OP1 = OP1 + Konst
;************************************************

addl16	macro op1,konst	; op1+konst -> op1

	movlw konst & H'FF'
	addwf op1,f

	movlw (konst >> 8) & H'FF'
	btfsc status,carry
	movlw ((konst >> 8)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	addwf op1+1,f

	endm

;************************************************
; 24 Bit Addition mit Konstante
; OP1 = OP1 + Konst
;************************************************

addl24	macro op1,konst	; op1+konst -> op1

	movlw konst & H'FF'
	addwf op1,f

	movlw (konst >> 8) & H'FF'
	btfsc status,carry
	movlw ((konst >> 8)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	addwf op1+1,f

	movlw (konst >> 16) & H'FF'
	btfsc status,carry
	movlw ((konst >> 16)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	addwf op1+2,f

	endm

;************************************************
; 32 Bit Addition mit Konstante
; OP1 = OP1 + Konst
;************************************************

addl32	macro op1,konst	; op1+konst -> op1

	movlw konst & H'FF'
	addwf op1,f

	movlw (konst >> 8) & H'FF'
	btfsc status,carry
	movlw ((konst >> 8)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	addwf op1+1,f

	movlw (konst >> 16) & H'FF'
	btfsc status,carry
	movlw ((konst >> 16)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	addwf op1+2,f

	movlw (konst >> 24) & H'FF'
	btfsc status,carry
	movlw ((konst >> 24)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	addwf op1+3,f

	endm

;************************************************
; 8 Bit Addition
; OP1 = OP1 + OP2
;************************************************

add8	macro op1,op2	; op1+op2->op1

	movfw op2
	addwf op1,f

	endm

;************************************************
; 16 Bit Addition
; OP1 = OP1 + OP2
;************************************************

add16	macro op1,op2	; op1+op2->op1

	movfw op2
	addwf op1,f

	movfw op2+1
	btfsc status,carry
	incfsz op2+1,w
	addwf op1+1,f

	endm

;************************************************
; 24 Bit Addition
; op1 = op1+op2
; op2 bleibt unverändert
;************************************************

add24	macro op1,op2	; op1+op2->op1

	movfw op2
	addwf op1,f

	movfw op2+1
	btfsc status,carry
	incfsz op2+1,w
	addwf op1+1,f

	movfw op2+2
	btfsc status,carry
	incfsz op2+2,w
	addwf op1+2,f

	endm

;************************************************
; 32 Bit Addition
; op1 = op1+op2
; op2 bleibt unverändert
;************************************************

add32	macro op1,op2	; op1+op2->op1

	movfw op2
	addwf op1,f

	movfw op2+1
	btfsc status,carry
	incfsz op2+1,w
	addwf op1+1,f

	movfw op2+2
	btfsc status,carry
	incfsz op2+2,w
	addwf op1+2,f

	movfw op2+3
	btfsc status,carry
	incfsz op2+3,w
	addwf op1+3,f

	endm

;************************************************
; 8 Bit Subtraktion mit Konstante
; OP1 = OP1 - Konst
;************************************************

subl8	macro op1,konst

	movlw konst & H'FF'
	subwf op1,f

	endm

;************************************************
; 16 Bit Subtraktion mit Konstante
; OP1 = OP1 - Konst
;************************************************

subl16	macro op1,konst

	movlw konst & H'FF'
	subwf op1,f

	movlw (konst >> 8) & H'FF'
	btfss status,carry
	movlw ((konst >> 8)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	subwf op1+1,f

	endm

;************************************************
; 24 Bit Subtraktion mit Konstante
; OP1 = OP1 - Konst
;************************************************

subl24	macro op1,konst

; byte1
	movlw konst & H'FF'
	subwf op1,f

; byte2
	movlw (konst >> 8) & H'FF'
	btfsc status,carry
	movlw ((konst >> 8)+1) & H'FF'
	andlw H'FF'
	bcf status,zero
	subwf op1+1,f

; byte3
	movlw (konst >> 16) & H'FF'
	btfsc status,carry
	movlw ((konst >> 16)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	subwf op1+2,f

	endm

;************************************************
; 32 Bit Subtraktion mit Konstante
; OP1 = OP1 - Konst
;************************************************

subl32	macro op1,konst

; byte1
	movlw konst & H'FF'
	subwf op1,f

; byte2
	movlw (konst >> 8) & H'FF'
	btfsc status,carry
	movlw ((konst >> 8)+1) & H'FF'
	andlw H'FF'
	bcf status,zero
	subwf op1+1,f

; byte3
	movlw (konst >> 16) & H'FF'
	btfsc status,carry
	movlw ((konst >> 16)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	subwf op1+2,f
; byte4
	movlw (konst >> 24) & H'FF'
	btfsc status,carry
	movlw ((konst >> 24)+1) & H'FF'
	andlw H'FF'
	btfss status,zero
	subwf op1+3,f

	endm

;************************************************
; 8 Bit Subtraktion
; OP1 = OP1 - OP2
;************************************************

sub8	macro op1,op2	; op1-op2->op1

	movfw op2
	subwf op1,f

	endm

;************************************************
; 16 Bit Subtraktion
; OP1 = OP1 - OP2
;************************************************

sub16	macro op1,op2	; op1-op2->op1

	movfw op2
	subwf op1,f

	movfw op2+1
	btfss status,carry
	incfsz op2+1,w
	subwf op1+1,f

	endm

;************************************************
; 24 Bit Subtraktion
; op1 = op1-op2
;************************************************

sub24	macro op1,op2

	movfw op2
	subwf op1,f

	movfw op2+1
	btfss status,carry
	incfsz op2+1,w
	subwf op1+1,f

	movfw op2+2
	btfss status,carry
	incfsz op2+2,w
	subwf op1+2,f

	endm

;************************************************
; 32 Bit Subtraktion
; op1 = op1-op2
;************************************************

sub32	macro op1,op2

	movfw op2
	subwf op1,f

	movfw op2+1
	btfss status,carry
	incfsz op2+1,w
	subwf op1+1,f

	movfw op2+2
	btfss status,carry
	incfsz op2+2,w
	subwf op1+2,f

	movfw op2+3
	btfss status,carry
	incfsz op2+3,w
	subwf op1+3,f
	
	endm

;************************************************
; Vergleichen
;************************************************

; Vergleich variable konstante
; Intern wird f+2er Complement von w gerechnet
; Bsp.
; f = 2, w = 2
; $2+($FD+1) = 0 , Überlauf hat stattgefunden, Ergebnis auch 0

; f > w c=1,z=0
; f = w c=1,z=1
; f < w c=0,z=0

;************************************************
; 8 Bit vergleich mit Konstante
;************************************************

cmpl8	macro variable,konstante

	movlw konstante & H'FF'	; konstante -> w
	subwf variable,w	; f-w->w

	endm

;************************************************
; 16 Bit vergleich mit Konstante
;************************************************

cmpl16	macro op1,konstante

	local cmp16end

	movlw (konstante >> 8) & H'FF'; 1.Byte (high)
	subwf op1+1,w
	btfss status,zero
	goto cmp16end

	movlw konstante & H'FF'	; 2.Byte (low)
	subwf op1,w
cmp16end
	endm

;************************************************
; 24 Bit vergleich mit Konstante
;************************************************

cmpl24	macro op1,konstante

	local cmp24_end

	movlw (konstante >> 16) & H'FF'	; 1.Byte
	subwf op1+2,w
	btfss status,zero
	goto cmp32_end

	movlw (konstante >> 8) & H'FF'	; 2.Byte
	subwf op1+1,w
	btfss status,zero
	goto cmp32_end

	movlw (konstante & H'FF')		; 3.Byte (Low)
	subwf op1,w
cmp24_end
	endm
;************************************************
; 32 Bit vergleich mit Konstante
;************************************************

cmpl32	macro op1,konstante

	local cmp32_end

	movlw (konstante >> 24) & H'FF'	; 1.Byte (High)
	subwf op1+3,w
	btfss status,zero
	goto cmp32_end

	movlw (konstante >> 16) & H'FF'	; 2.Byte
	subwf op1+2,w
	btfss status,zero
	goto cmp32_end

	movlw (konstante >> 8) & H'FF'	; 3.Byte
	subwf op1+1,w
	btfss status,zero
	goto cmp32_end

	movlw (konstante & H'FF')		; 4.Byte (Low)
	subwf op1,w
cmp32_end
	endm

;************************************************
; 8 Bit vergleich
;************************************************

cmp8	macro variable1,variable2

	movfw variable2	; variable2 -> w
	subwf variable1,w	; f-w->w

	endm

;************************************************
; 16 Bit vergleich
;************************************************

cmp16	macro op1,op2

	local cmp16end

	movfw op2+1	; 1.Byte (high)
	subwf op1+1,w
	btfss status,zero
	goto cmp16end

	movfw op2	; 2.Byte (low)
	subwf op1,w
cmp16end
	endm

;************************************************
; 24 Bit vergleich
;************************************************

cmp24	macro op1,op2

	local cmp24_end

	movfw op2+2		; 1.Byte
	subwf op1+2,w
	btfss status,zero
	goto cmp32_end

	movfw op2+1		; 2.Byte
	subwf op1+1,w
	btfss status,zero
	goto cmp32_end

	movfw op2		; 3.Byte (Low)
	subwf op1,w
cmp24_end
	endm

;************************************************
; 32 Bit vergleich
;************************************************

cmp32	macro op1,op2

	local cmp32_end

	movfw op2+3		; 1.Byte (High)
	subwf op1+3,w
	btfss status,zero
	goto cmp32_end

	movfw op2+2		; 2.Byte
	subwf op1+2,w
	btfss status,zero
	goto cmp32_end

	movfw op2+1		; 3.Byte
	subwf op1+1,w
	btfss status,zero
	goto cmp32_end

	movfw op2		; 4.Byte (Low)
	subwf op1,w
cmp32_end
	endm

;************************************************
; Multiplikation 8 Bit ohne Vorzeichen
; 16 Bit Ergebnis in result
; op2 wird zerstört
;
; benötigt 1 freies Byte ab Adresse tmp
; tmp = Zähler
;************************************************

mulu8	macro op1,op2,result

	local mulu8_0

	clrf16 result	; ergebnis löschen

	movlw 8	; Zähler setzen
	movwf tmp
	movfw op1
	clc

mulu8_0	rrf op2,f
	btfsc status,carry
	addwf result+1,f

	rrf16 result	; /2

	decfsz tmp,f
	goto mulu8_0

	endm

;************************************************
; Multiplikation 8 Bit mit Vorzeichen
; 16 Bit Ergebnis in result
; op1+op2 werden zerstört
;
; benötigt 2 freie Bytes ab Adresse tmp
; tmp   = Zähler
; tmp+1 = Vorzeichen
;************************************************

muls8	macro op1,op2,result

	local muls8_0,muls8_1,muls8_2,muls8_3

	clrf16 result	; ergebnis löschen

	movfw op1	; vorzeichen festhalten
	xorwf op2,w
	movwf tmp+1

	btfss op1,7	; negativ ?
	goto muls8_0	; nein 
	neg8 op1

muls8_0	btfss op2,7	; dito
	goto muls8_1
	neg8 op2

muls8_1	movlw 8	; Zähler setzen
	movwf tmp
	movfw op1
	clc

muls8_2	rrf op2,f
	btfsc status,carry
	addwf result+1,f

	rrf16 result	; /2

	decfsz tmp,f
	goto muls8_2

	btfss tmp+1,7
	goto muls8_3
	neg16 result
muls8_3
	endm

;************************************************
;
; Multiplikation 16 Bit ohne Vorzeichen
; 32 Bit Ergebnis in result
; op2 wird zerstört
;
; benötigt 1 freies Byte ab Adresse tmp
; tmp = Zähler
;
;************************************************

mulu16	macro op1,op2,result

	local mulu16_0,mulu16_1,mulu16_2,mulu16_3

	clrf32 result	; ergebnis löschen

mulu16_1	movlw 16	; Zähler setzen
	movwf tmp
	clc	; carry löschen

mulu16_2	rrf16 op2	; Bit rausschieben

	jcc mulu16_3
	add16 result+2,op1	; Carry gesetzt -> aufaddieren
mulu16_3	rrf32 result

	decfsz tmp,f
	goto mulu16_2

	endm

;************************************************
; Multiplikation 16 Bit mit Vorzeichen
; 32 Bit Ergebnis in result
; op1+op2 werden zerstört
;
; benötigt 2 freie Bytes ab Adresse tmp
; tmp+0 = Zähler
; tmp+1 = Vorzeichen
;************************************************

muls16	macro op1,op2,result

	local muls16_0,muls16_1,muls16_2,muls16_3,muls16exit

	clrf32 result	; ergebnis löschen

	movfw op1+1
	xorwf op2+1,w	; Vorzeichen
	movwf tmp+1

	btfss op1+1,7	; negativ ?
	goto muls16_0	; ist positiv
	neg16 op1

muls16_0	btfss op2+1,7	; negativ ?
	goto muls16_1	; ist positiv
	neg16 op2		

muls16_1	movlw 16	; Zähler setzen
	movwf tmp
	clc	; carry löschen

muls16_2	rrf16 op2	; Bit rausschieben

	jcc muls16_3
	add16 result+2,op1	; Carry gesetzt -> aufaddieren

muls16_3	rrf32 result

	decfsz tmp,f
	goto muls16_2

	btfss tmp+1,7
	goto muls16exit
	neg32 result
muls16exit
	endm

;************************************************
;
; Multiplikation 32 Bit ohne Vorzeichen
; 64 Bit Ergebnis in result
; op2 wird zerstört
; op1 und op2 = 32 Bit
;
; benötigt 1 freies Byte ab Adresse tmp
; tmp = Zähler
;
;************************************************

mulu32	macro op1,op2,result

	local mulu32_1,mulu32_2,mulu32_3

	clrf64 result	; ergebnis löschen

mulu32_1	movlw 32	; Zähler setzen
	movwf tmp
	clc	; carry löschen

mulu32_2	rrf32 op2	; Bit rausschieben

	jcc mulu32_3
	add32 result+4,op1 ; Carry gesetzt -> aufaddieren

mulu32_3	rrf64 result

	decfsz tmp,f
	goto mulu32_2

	endm

;************************************************
;
; Multiplikation 32 Bit mit Vorzeichen
; 64 Bit Ergebnis in result
; op1 und op2 werden zerstört
; op1 und op2 = 32 Bit
;
; benötigt 2 freie Byte ab Adresse tmp
; tmp+0 = Zähler
; tmp+1 = Vorzeichen
;
;************************************************

muls32	macro op1,op2,result

	local muls32_0,muls32_1,muls32_2,muls32_3,muls32_exit

	clrf64 result	; ergebnis löschen

	movfw op1+3
	xorwf op2+3,w
	movwf tmp+1

	btfss op1+3,7
	goto muls32_0
	neg32 op1

muls32_0	btfss op2+3,7
	goto muls32_1
	neg32 op2

muls32_1	movlw 32	; Zähler setzen
	movwf tmp
	clc	; carry löschen

muls32_2	rrf32 op2	; Bit rausschieben

	jcc muls32_3
	add32 result+4,op1	; Carry gesetzt -> aufaddieren

muls32_3	rrf64 result

	decfsz tmp,f
	goto muls32_2

	btfss tmp+1,7
	goto muls32_exit
	neg64 result
muls32_exit
	endm

;************************************************
;
; Division 8 Bit ohne Vorzeichen
; Rest in op1
;
; op1 und op2 werden zerstört
; Ergebnis in result
;
; benötigt 1 freies Byte ab Adresse tmp
; tmp+0 = Zähler
;
;************************************************

divu8	macro op1,op2,result

	local divu8_1,divu8_2,divu8_3,divu8_4,divu8exit

	clrf result	; ergebnis löschen

	movfw op2
	jz divu8exit	; Division durch 0

divu8_1	movlw 1
	movwf tmp

	clc

divu8_2	jbs op2,7,divu8_3 ; op2 linksbündig
	incf tmp,f	; mitzählen
	rlf op2,f	; schieben
	goto divu8_2

divu8_3	cmp8 op1,op2	; Op1 >= op2 -> Carry=1
	jl divu8_4

	sub8 op1,op2	; subtrahieren
	sec
divu8_4	rlf result,f	; nach ergebnis

	rrf op2,f	; op2/2

	decfsz tmp,f
	goto divu8_3
divu8exit
	endm

;************************************************
; Division 8 Bit mit Vorzeichen
; Rest in op1
;
; op1 und op2 werden zerstört
;
; benötigt 2 freie Bytes ab Adresse tmp
; tmp+0 = Zähler
; tmp+1 = Vorzeichen
;************************************************

divs8	macro op1,op2,result

	local divs8_0,divs8_1,divs8_2,divs8_3,divs8_4,divs8exit

	clrf result	; ergebnis löschen

	movfw op2
	jz divs8exit	; Division durch 0

	xorwf op1,w	; Vorzeichen
	movwf tmp+1

	btfss op1,7	; negativ ?
	goto divs8_0
	neg8 op1
	
divs8_0	btfss op2,7	; negativ ?
	goto divs8_1
	neg8 op2

divs8_1	movlw 1
	movwf tmp

	clc

divs8_2	jbs op2,7,divs8_3 ; op2 linksbündig
	incf tmp,f	; mitzählen
	rlf op2,f	; schieben
	goto divs8_2

divs8_3	cmpv op1,op2	; Op1 >= op2 -> Carry=1
	jl divs8_4

	sub8 op1,op2	; subtrahieren
	sec
divs8_4	rlf result,f	; nach ergebnis

	rrf op2,f	; op2/2

	decfsz tmp,f
	goto divs8_3

	btfss tmp+1,7	; war negativ ?
	goto divs8exit
	neg8 result
divs8exit
	endm

;************************************************
; Division 16 Bit ohne Vorzeichen
; Rest in op1
;
; op1 und op2 werden zerstört
;
; benötigt 1 freies Byte ab Adresse tmp
; tmp+0 = Zähler
;************************************************

divu16	macro op1,op2,result

	local divu16_1,divu16_2,divu16_3,divu16_4,divu16exit

	clrf16 result	; ergebnis löschen

	movfw op2
	iorwf op2+1,w
	jz divu16exit	; Division durch 0

divu16_1	movlw 1
	movwf tmp

	clc

divu16_2	jbs op2+1,7,divu16_3	; op2 linksbündig
	incf tmp,f	; mitzählen
	rlf16 op2	; schieben
	goto divu16_2

divu16_3	cmp16 op1,op2	; Op1 >= op2 -> Carry=1
	jl divu16_4

	sub16 op1,op2	; subtrahieren
	sec

divu16_4	rlf16 result	; nach ergebnis

	rrf16 op2	; op2/2

	decfsz tmp,f
	goto divu16_3

divu16exit
	endm

;************************************************
; Division 16 Bit mit Vorzeichen
; Rest in op1
;
; op1 und op2 werden zerstört
;
; benötigt 2 freie Bytes ab Adresse tmp
; tmp+0 = Zähler
; tmp+1 = Vorzeichen
;************************************************

divs16	macro op1,op2,result

	local divs16_0,divs16_1,divs16_2,divs16_3,divs16_4,divs16exit

	clrf16 result	; ergebnis löschen

	movfw op2
	iorwf op2+1,w
	jz divs16exit	; Division durch 0

	movfw op1+1	; Vorzeichen
	xorwf op2+1,w
	movwf tmp+1

	btfss op1+1,7	; negativ ?
	goto divs16_0
	neg16 op1
	
divs16_0	btfss op2+1,7	; negativ ?
	goto divs16_1
	neg16 op2

divs16_1	movlw 1
	movwf tmp

	clc

divs16_2	jbs op2+1,7,divs16_3	; op2 linksbündig
	incf tmp,f	; mitzählen
	rlf16 op2	; schieben
	goto divs16_2

divs16_3	cmp16 op1,op2	; Op1 >= op2 -> Carry=1
	jl divs16_4

	sub16 op1,op2	; subtrahieren
	sec

divs16_4	rlf16 result	; nach ergebnis

	rrf16 op2	; op2/2

	decfsz tmp,f
	goto divs16_3

	btfss tmp+1,7	; war negativ ?
	goto divs16exit
	neg16 result
divs16exit
	endm

;************************************************
; Division 32 Bit ohne Vorzeichen
; Rest in op1
; benötigt 1 freies Byte ab Adresse tmp
; tmp+0 = Zähler
;************************************************

divu32	macro op1,op2,result

	local div_0,div_1,div_2,div_4,div_5,divexit
	
	clrf32 result	; ergebnis löschen

	movfw op2	; Division : 0 ?
	iorwf op2+1,w
	iorwf op2+2,w
	iorwf op2+3,w
	jz divexit

div_5	movlw 1
	movwf tmp

	clc

div_0	jbs op2+3,7,div_1	; op2 linksbündig
	incf tmp,f	; mitzählen
	rlf32 op2	; schieben
	goto div_0

div_1	cmp32 op1,op2	;
	jl div_2
	sub32 op1,op2	; op1-op2 -> op1
	sec

div_2	rlf32 result	; nach ergebnis

	rrf32 op2	; op2/2

	decfsz tmp,f
	goto div_1

divexit
	endm

;************************************************
; Division 32 Bit mit Vorzeichen
; Rest in op1
; benötigt 2 freie Bytes ab Adresse tmp
; tmp+0 = Zähler
; tmp+1 = Vorzeichen
;************************************************

divs32	macro op1,op2,result

	local div_0,div_1,div_2,div_4,div_5,divexit
	
	clrf32 result	; ergebnis löschen

	movfw op2	; Division : 0 ?
	iorwf op2+1,w
	iorwf op2+2,w
	iorwf op2+3,w
	jz divexit

	movfw op1+3	; Vorzeichen ?
	xorwf op2+3,w
	movwf tmp+1

	jbc op1+3,7,div_4	; negativ ?
	neg32 op1		; negieren

div_4	jbc op2+3,7,div_5	; negativ ?
	neg32 op2		; negieren

div_5	movlw 1
	movwf tmp

	clc

div_0	jbs op2+3,7,div_1	; op2 linksbündig
	incf tmp,f	; mitzählen
	rlf32 op2	; schieben
	goto div_0

div_1	cmp32 op1,op2	;
	jl div_2
	sub32 op1,op2	; op1-op2 -> op1
	sec

div_2	rlf32 result	; nach ergebnis

	rrf32 op2	; op2/2

	decfsz tmp,f
	goto div_1

	btfss tmp+1,7	; war negativ ?
	goto divexit
	neg32 result
divexit
	endm

;************************************************
; Binär nach BCD 16-Bit
;
; BIN2BCD16
;
; Eingabe:
; BIN = 16-Bit Variable
; NU  = Null unterdrücken
;
; Ausgabe:
; BCD = 5 Byte ASC-Codiert
;
; designed for speed
;************************************************

BIN2BCD16	macro BIN,BCD,NU

	local bb1,bb2,bb3,bb4,bb5,bb6,bb7,bb8,bb9
	movlw A'0'
	movwf bcd
	movwf bcd+1
	movwf bcd+2
	movwf bcd+3
	movwf bcd+4

; 10000

bb1	subl16 bin,10000
	jcc bb2
	incf bcd,f
	goto bb1
bb2	addl16 bin,10000

; 1000

bb3	subl16 bin,1000
	jcc bb4
	incf bcd+1,f
	goto bb3
bb4	addl16 bin,1000

; 100

bb5	subl16 bin,100
	jcc bb6
	incf bcd+2,f
	goto bb5
bb6	addl16 bin,100

; 10

bb7	subl16 bin,10
	jcc bb8
	incf bcd+3,f
	goto bb7
bb8	addl16 bin,10

; 1

bb9	movfw bin
	addwf bcd+4,f

	if nu == 1
	  cmpl8 bcd,A'0'
	  btfss status,zero
	  return
	  bcf bcd,4

	  cmpl8 bcd+1,A'0'
	  btfss status,zero
	  return
	  bcf bcd+1,4

	  cmpl8 bcd+2,A'0'
	  btfss status,zero
	  return
	  bcf bcd+2,4

	  cmpl8 bcd+3,A'0'
	  btfss status,zero
	  return
	  bcf bcd+3,4

	endif

	return

	endm


	list

