;=====================================================================
;=              PARTIE CALCUL DU CODEUR ANGULAIRE ABSOLU             =
;=====================================================================

;Directives d'assemblage
;=======================

		.title "convdif.asm"
		.vers "st6215"
		.input "6215_reg.asm"
		.w_on		; pour autoriser les syntaxes label.P
				; et label.W
		.org 00h

;Donnees en memoire ROM
;======================
tablog01	.word 0, 7702, 12207, 15404, 17883, 19909, 21622, 23106
		.word 24415, 25585, 26644, 27611, 28501, 29324, 30091, 30808
		.word 31482, 32117, 32717, 33287, 33830, 34346, 34840, 35313
		.word 35767, 36203, 36622, 37026, 37416, 37793, 38157, 38510
		.word 38852, 39184, 39506, 39819, 40123, 40419, 40708, 40989
		.word 41264, 41532, 41793, 42048, 42298, 42542, 42781, 43015
		.word 43244, 43469, 43689, 43905, 44116, 44324, 44528, 44728
		.word 44925, 45118, 45308, 45495, 45678, 45859, 46037, 46212
		.word 46384, 46554, 46721, 46886, 47048, 47208, 47365, 47521
		.word 47674, 47825, 47974, 48121, 48267, 48410, 48552, 48691
		.word 48829, 48966, 49100, 49234, 49365, 49495, 49623, 49750
		.word 49876, 50000, 50123, 50244, 50364, 50483, 50601, 50717
		.word 50832, 50946, 51059, 51171, 51281, 51391, 51499, 51607
		.word 51713, 51818, 51923, 52026, 52128, 52230, 52330, 52430
		.word 52529, 52627, 52724, 52820, 52915, 53010, 53104, 53197
		.word 53289, 53380, 53471, 53561, 53650, 53739, 53827, 53914
		.word 54000, 54086, 54171, 54256, 54340, 54423, 54506, 54588
		.word 54669, 54750, 54830, 54910, 54989, 55067, 55145, 55223
		.word 55300, 55376, 55452, 55527, 55602, 55676, 55750, 55823
		.word 55896, 55969, 56041, 56112, 56183, 56254, 56324, 56393
		.word 56463, 56531, 56600, 56668, 56735, 56802, 56869, 56935
		.word 57001, 57067, 57132, 57197, 57261, 57325, 57389, 57452
		.word 57515, 57578, 57640, 57702, 57764, 57825, 57886, 57946
		.word 58007, 58066, 58126, 58185, 58244, 58303, 58361, 58419
		.word 58477, 58534, 58592, 58648, 58705, 58761, 58817, 58873	
		.word 58928, 58983, 59038, 59093, 59147, 59201, 59255, 59309
		.word 59362, 59415, 59468, 59520, 59573, 59625, 59676, 59728
		.word 59779, 59830, 59881, 59932, 59982, 60032, 60082, 60132
		.word 60182, 60231, 60280, 60329, 60377, 60426, 60474, 60522
		.word 60570, 60617, 60665, 60712, 60759, 60806, 60852, 60899
		.word 60945, 60991, 61037, 61082, 61128, 61173, 61218, 61263
		.word 61308, 61352, 61397, 61441, 61485, 61529, 61572, 65535

tablog02	.word 194, 582, 971, 1361, 1753, 2147, 2543, 2943
		.word 3346, 3754, 4167, 4585, 5010, 5442, 5881, 6329
		.word 6786, 7254, 7734, 8226, 8732, 9254, 9793, 10352
		.word 10932, 11535, 12165, 12825, 13519, 14251, 15027, 15854
		.word 16739, 17693, 18729, 19864, 21121, 22530, 24136, 26006
		.word 28247, 31048, 34794, 40474, 52684, 65535, 0, 0

decimal		.byte 00, 00, 01, 00, 00, 02, 00, 00
		.byte 04, 00, 00, 08, 00, 01, 06, 00
		.byte 03, 02, 00, 06, 04, 01, 02, 08

;Constantes
===========

watch		.equ 0FEh

;Adresses registres
;==================

flgxs		.def 84h	;signe de xs
flgys		.def 85h	;signe de ys
xbin		.def 88h	;poids binaire de xa
ybin		.def 89h	;poids binaire de ya
flg90		.def 86h
prom		.def 87h	; copie du DRWR
nummsb		.def 8Ah
numlsb		.def 8Bh
denmsb		.def 8Ch
denlsb		.def 8Dh
difmsb		.def 8Eh
diflsb		.def 8Fh
alpha0		.def 90h
alpha1		.def 91h
alphamsb	.def 92h
alphalsb	.def 93h
cent		.def 94h
diz		.def 96h
unit		.def 98h

;Programme principal
;===================

reset		ldi wdr, watch	; pour faire patienter le chien de garde
		call convlog	; conversion de x et y en log

		ldi wdr, watch	; pour faire patienter le chien de garde
		call diflog	; difference des logs

		ldi wdr, watch	; pour faire patienter le chien de garde
		call base	; determination de l'angle de base

		ldi wdr, watch	; pour faire patienter le chien de garde
		call compl

		ldi wdr, watch	; pour faire patienter le chien de garde
		call secteur

		ldi wdr, watch	; pour faire patienter le chien de garde
		call bcd

arret		jp arret

;Procedure conversion xb en log(xb) et yb en log(yb)
;===================================================
	
convlog		clr flg90	; preparation du drapeau de
		ld A, ybin	; comparaison de x et y. par defaut,
		cp A, xbin	; il est mis a 0 pour dire x < y
		jrnc convlog1

		ldi flg90, 1	; ou a 1 pour dire x < y

convlog1	ldi prom, tablog01.w	; registre page fenetre au
		ld A,prom	; debut de table
		ld drwr, A	; recopie dans le registre de page
		ld a, xbin
		dec a
		call pagerom	; reajustement page fenetre selon x
		ld xbin, a
		add a, a	; a * 2 car c'est une table 
		addi A, tablog01.d	; de valeurs sur deux octets
		ld X, A		; registre d'index pointe en fenetre
		ld A, flg90	; selon la comparaison ci dessus,
		jrz convlog3

		ld A, (X)	; x va dans le numerateur (poids faible)
		ld numlsb, A
		inc X
		ld A, (X)	; et poids fort
		ld nummsb, A
		jp convlog4

convlog3	ld A, (x)	; ou bien x va dans le denominateur
		ld denlsb, A	; poids faible
		inc X
		ld A, (X)	; et poids fort
		ld denmsb, A

convlog4	ldi prom, tablog01.w	; calcul du log de y, meme principe
		ld A,prom
		ld drwr, A	; recopie dans le registre de page
		ld a, ybin
		dec a
		call pagerom	
		ld ybin, a
		add a, a	; a * 2 car c'est une table 
		addi A, tablog01.d	; de valeurs sur deux octets
		ld Y, A
		ld A, flg90
		jrnz convlog5

		ld A, (Y)	; et y va dans le numerateur
		ld numlsb, A
		inc Y
		ld a, (y)
		ld nummsb, a
		jp convlog6

convlog5	ld A, (Y)	; ou dans le denominateur
		ld denlsb, A
		inc Y
		ld A, (Y)
		ld denmsb, A
convlog6	ret

;Choix de la page du tableau
;===========================
;Noter que les 64 octets du tableau ne font que 32 valeurs de deux octets

pagerom		cpi a, 32	; si a < 32, on est dans la bonne page
		jrc pagerom1
		ld v, a
		inc prom	; sinon, on essaye la page suivante
		ld A,prom
		ld drwr, A	; recopie dans le registre de page
		ld a, v
		subi a, 32	; en retirant 32 de a pour pointer encore 
		jp pagerom	; dans la fenetre, et on repete le tout
pagerom1	ret

;Procedure difference des logarithmes
;====================================

diflog		ld A, numlsb	; poids faible du numerateur
		sub a, denlsb	; - poids faible du denominateur
		jrnc diflog1
		inc denmsb	; (si retenue, on incremente le poids
				;  fort du denominateur)
diflog1		ld diflsb, A	; va dans poids faible du resultat
		ld A, nummsb	; poids fort du numerateur
		sub a, denmsb	; - poids fort du denominateur
		ld difmsb, A	; va dans poids fort du resultat
		ret

;Determination de l'angle de base: alpha0
;========================================
; recherche de l'angle dont le log(cotg) se rapproche le plus
; de la difference des logs de x et de y

base		ldi prom, tablog02.w	; debut de la table des log(cotg)
		ld A,prom
		ld drwr, A	; recopie dans le registre de page
		ldi alpha0, 45
base1		ldi x, tablog02.d	; x pointe sur le debut de la
					; fenetre
base2		inc x
		ld a, (x)
		cp a, difmsb	; poids fort de la difference est il plus
		jrc base3	; grand que la valeur dans la table ?
		jp base5

base3		inc x		; oui : valeur suivante de la table
		inc alpha0	; incrementation resultat en degres
		ld a, x
		cpi  a, 128	; fin de la fenetre ?
		jrc base4

		inc prom	; oui : fenetre suivante et bouclage
		ld A,prom
		ld drwr, A	; recopie dans le registre de page
		jp base1

base4 		jp base2	; non : on continue dans cette fenetre

base5		jrz base6	; non : plus petit que valeur table ?

		ret		; oui : fin de conversion

base6		dec x		; non, egal: comparaison poids faibles
		ld a, (x)	; on recule le pointeur d'un cran
		cp a, diflsb	; diff faible > val. table faible?
		jrc base7

		ret		; oui : fin de conversion

base7		inc x		; non : suite de la boucle
		jp base3

;Determination de alpha1: angle du premier secteur
;=================================================

compl		ld a, flg90	; si x < y, le vrai resultat sera 
		jrnz compl1
		ld a, alpha0
		ld alpha1, a
		ret
compl1		ldi a, 90	; 90-alpha
		sub a, alpha0
		ld alpha1, a
		ret

;Determination du secteur et du poids binaire de l'angle
;=======================================================	
secteur		clr alphamsb	; division de 360 degres en 2 zones
		ld a, flgys
		jrz secteur1
		jp secteur3

secteur1	ld a, flgxs	; y positif : 0 < angle < 180
		jrnz secteur2
		ld a, alpha1	; x positif : 0 < angle < 90
		ld alphalsb, a
		ret
secteur2	call alphcalc	; x negatif : 90 <angle < 180
		ret		; angle = 180 - alpha

secteur3	ld a, flgxs	; y negatif : 180 < angle <360
		jrnz secteur4
		jp secteur6

secteur4	ld a, alpha1	; x negatif : 180 < angle < 270
		addi a, 180	; angle = 180 + alpha
		jrnc secteur5
		inc alphamsb	; il y aura necessairement une retenue 
secteur5	ld alphalsb, a
		ret

secteur6	call alphcalc	; x positif : 270 < angle < 360
				; angle = 360 - alpha
		addi a, 180	; deux etapes : (180 - alpha) + 180
		inc alphamsb	; il y aura necessairement une retenue 
		ld alphalsb, a
		ret

;calcul de 180 degres moins alpha1 
;=================================
alphcalc	ldi a, 180
		sub a, alpha1
		ld alphalsb, a
		ret

;Conversion binaire decimale sur 2 octets
;========================================
bcd		clr cent
		clr diz
		clr unit
		jrr 0, alphamsb, bcd1	; si poids for angle = 1,
					; non ajoute 256
		ldi cent, 2
		ldi diz, 5
		ldi unit, 6
bcd1		ldi drwr, decimal.w	; la table decimal contient
					; des groupes de
		ldi x, decimal.d+23	; 3 octets representant les chiffres
					; decimaux pour chacune des
					; puissances de 2
bcd2		jrs 7, alphalsb, bcd3	; si bit de poids fort de
					; alphalsb = 0, suivant
		dec x
		dec x
		jp bcd8

bcd3		ld a, unit	; sinon, on ajoute les trois chiffres
				; pointes par x
		add a, (x)	; respectivement aux unites ...
		ld unit, a
		cpi a, 10	; debordement ?
		jrnc bcd4
		jp bcd6

bcd4		subi a, 10	; oui, retenue : on incremente les dizaines
		ld unit, a
		inc diz
		ld a, diz
		cpi a, 10

bcd6		dec x		; chiffre suivant, a ajouter aux dizaines 
		ld a, diz
		add a, (x)
		ld diz, a
		cpi a, 10	; debordement ?
		jrc bcd7

		subi a, 10	; oui, retenue : on incremente les centaines
		ld diz, a
		inc cent

bcd7		dec x		; chiffre suivant, a ajouter aux centaines 
		ld a, cent
		add a, (x)
		ld cent, a
bcd8		ld a, x
		cpi a, decimal.d	; fin de la table ?
		jrz bcd9
		ld a, alphalsb	; non : decalage a gauche du
				; nombre a convertir
		sla a
		ld alphalsb, a
		dec x		; prochaine valeur de la table
		jp bcd2		; bouclage

bcd9		ret		; oui : fin de conversion

;Demarrage
;=========
		.org 0FFEh
res		jp reset

