;==================================================================
;=                      GIROUETTE A EFFET HALL                    =
;==================================================================


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

		.title "GIRHALL.ASM"
		.vers "st6215"
		.input "6215_reg.asm"
		.romsize 4
		.w_on

;Donnees en memoire ROM
;======================

		.org 00h

tablog00	.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

tablog01	.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 xa
flgys		.def 85h		; signe de ya
xbin		.def 86h		; poids binaire de xa
ybin		.def 87h		; poids binaire de ya
denbin		.def 88h		; pds bin denominateur
numbin		.def 89h		; pds bin numerateur
numlsb		.def 8Bh		; log lsb numerateur
nummsb		.def 8Ah		; log msb numerateur
denlsb		.def 8Dh		; log lsb denominateur
denmsb		.def 8Ch		; log msb denominateur
diflsb		.def 8Fh		; difference log lsb
difmsb		.def 8Eh		; difference log msb
ligne		.def 90h		; ligne du tableau
page		.def 91h		; page du tableau
alpha0		.def 92h		; angle de base
alpha1		.def 93h		; angle du 1er secteur
alphalsb	.def 94h		; lsb de l'angle final
alphamsb	.def 95h		; msb de l'angle final
cent		.def 96h		; code bcd des centaines
diz		.def 98h		; code bcd des dizaines
unit		.def 9Ah		; code bcd des unites
polar		.def 9Ch		; polarite du LCD

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

;Initialisations

reset		ldi wdr,watch		; chargt chien de garde

		ldi ddrb,0FFh		; port B: 8 sorties
		clr orb			; drain ouvert pour "emu"

		clr ddrc		; Port C: xs sur pc6 
		clr orc			; ys sur pc7
		ldi drc,3Fh		; xa sur pc4
					; ya sur pc5
					; 4 entrees sans interruption
					; pc6, pc7, avec rappel
					; pc4, pc5, sans rappel
		ldi ddra,0FFh		; Port A: 8 sorties 
		ldi ora,0FFh		; symetriques sans inter-
					; -ruption pour le LCD
		ldi ior,10h		; autoriser interruption
					; pour le CAN
		clr polar		; plan arriere LCD

debut		ldi wdr,watch		; programme principal
		call signe		; determination du signe

		ldi wdr, watch		; pour faire patienter le chien
		call analog		; acquisitions analogiques

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

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

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

		ldi wdr, watch		; pour faire patienter le chien
		call compl		; tangeante ou cotangeante

		ldi wdr, watch		; pour faire patienter le chien
		call secteur		; determination du quadrant

		ldi wdr, watch		; pour faire patienter le chien
		call bcd		; conversion pour affichage

		ldi wdr, watch		; pour faire patienter le chien
		call gestion		; affichage

		jp debut

;Acquisition des signes de xa et ya: resultats dans flgxs et flgys
;"1" si negatif, "0" si positif
;=================================================================

signe		clr flgxs		; si pc6 (xs)="1"
		clr flgys		; (signe positif)
		jrs 6,drc,signe1	; "0" dans flgxs
		ldi flgxs,01		; idem pour flgys

signe1		jrs 7,drc,signe2
		ldi flgys,01

signe2		ret

;Acquisition analogique: resultats dans xbin et ybin
;===================================================

analog		set 4,orc		; pc4=entree analogique
		ldi adcr,90h		; activer CAN
		nop
		nop
		ldi adcr,0B0h		; autorise interruption
		wait			; en veille pendant 
		ld a,adr		; acquisition
		ldi adcr,90h
		ld xbin,a		; resultat dans xbin
		res 4,orc

		set 5,orc		; idem pour ya dans ybin
		ldi adcr,0B0h
		wait
		ld a,adr
		clr adcr
		ld ybin,a
		res 5,orc
		ret

;Test xbin >= ybin: xbin dans numbin et ybin dans
;denbin, sinon l'inverse.Conversion denbin en 
;log(denbin) et numbin en log(numbin).
;resultats stockes dans numlsb,nummsb,denlsb,denmsb.
;===================================================

convlog		ld a,xbin		; comparaison de x et de y
		cp a,ybin
		jrc conv1
		ld numbin,a		; x > y
		ld a,ybin
		ld denbin,a
		jp conv2

conv1		ld denbin,a		; x < y
		ld a,ybin
		ld numbin,a

conv2		clr page		; prepare l'initialisation de
		ld a,denbin		; tablog00
		call pgln
		ld denlsb,a		; lsb de la donnee dans denlsb
		inc x
		ld a,(x)
		ld denmsb,a		; msb de la donnee dans denmsb

		ldi wdr,watch
		clr page		; nouvelle initialisation de
		ld a,numbin		; tablog00 pour le numerateur
		call pgln
		ld numlsb,a
		inc x
		ld a,(x)
		ld nummsb,a

		ret

;pointeur de page, pointeur de ligne

pgln		dec a			; pour pointer l'adresse basse
					; de la donnee
pgln1		cpi a,32		; cherche la bonne page
		jrc pgln2
		subi a,32
		inc page
		jp pgln1

pgln2		sla a			; multiplier par 2 l'adresse ligne
		ld ligne,a		; car mots de 2 octets
		ld a,page		; pointer page
		addi a,tablog00.w
		ld drwr,a
		ld a,ligne		; pointer ligne
		addi a,tablog00.d
		ld x,a			; adresse du lsb dans x
		ld a,(x)
		ret

;Procedure difference des logarithmes,
;resultats stockes dans diflsb et difmsb.
;========================================

diflog		ld a,numlsb		; lsb numerateur - lsb denominateur
		sub a,denlsb
		jrnc diflog1
		inc denmsb		; si retenue: incrementer
					; msb du denominateur
diflog1		ld diflsb,a		; lsb de la difference
		ld a,nummsb		; msb numerateur - msb denominateur
		sub a,denmsb
		ld difmsb,a		; msb de la difference
		ret

;calcul de l'angle de base: alpha0
;entre 45 et 90 degres,donne par le
;tableau tablog01, compare a diflog(msb,lsb)
;==========================================

base		ldi drwr,tablog01.w	; initialise tablog01
		ldi alpha0,45
base1		ldi x,tablog01.d	; pointe la 1ere ligne

base2		inc x			; pointe le msb de la donnee
		ld a,(x)
		cp a,difmsb		; comparaison
		jrc base3
		jp base5

base3		inc x
		inc alpha0		; prepare la comparaison suivante
		ld a,x
		cpi  a,80h		; doit-on changer de page?
		jrc base4

		ldi a,tablog01.w	; pointer 2eme et derniere page
		inc a
		ld drwr,a
		jp base1

base4 		jp base2

base5		jrz base6

		ret

base6		dec x			; comparaison relative au lsb
		ld a,(x)
		cp a,diflsb
		jrc base7

		ret

base7		inc x
		jp base3

;Determination de alpha1: angle du premier secteur
;alpha1=alpha0 si ybin>=xbin, sinon alpha1=90-alpha0.
;====================================================

compl		ld a,ybin
		cp a,xbin
		jrc compl1		; si x > y, le resultat sera

		ld a,alpha0
		ld alpha1,a
		ret

compl1		ldi a,90
		sub a,alpha0		; 90 - alpha
		ld alpha1,a
		ret

;Determination du secteur et du poids binaire de l'angle,
;choix possibles:
;alpha= alpha1,= 180-alpha1,= 180+alpha1,= 360-alpha1.
;========================================================

secteur		clr alphamsb
		ld a,flgys
		jrnz secteur3

secteur1	ld a,flgxs		; y > 0 -> 0 < alpha < 180
		jrnz secteur2
		ld a,alpha1		; 0 < alpha < 90
		ld alphalsb,a
		ret

secteur2	call alphcalc		; 90 < alpha < 180
		ret

secteur3	ld a,flgxs
		jrnz secteur4
		jp secteur6


secteur4	ld a,alpha1		; x < 0 -> 180 < alpha < 270
		addi a,180
		jrnc secteur5
		inc alphamsb		; parce qu'il y a retenue

secteur5	ld alphalsb,a
		ret

secteur6	call alphcalc		; 270 < alpha < 360
		addi a,180
		inc alphamsb		; retenue systematique
		ld alphalsb,a
		ret

;calcul de 180 degres - alpha1 

alphcalc	ldi a,180
		sub a,alpha1
		ld alphalsb,a
		ret

;conversion binaire decimale sur 2 octets
;resultats dans cent, diz et unit.
;========================================

bcd		clr cent
		clr diz
		clr unit
		jrr 0,alphamsb,bcd1	; si alphamsb = "1",
		ldi cent,02		; on ajoute 256
		ldi diz,05
		ldi unit,06

bcd1		ldi drwr,decimal.w	; la table "decimal" contient
		ldi x,decimal.d+17h	; des groupes de 3 octets
					; representant les chiffres decimaux
					; pour chacune des puissances de 2
bcd2		jrs 7,alphalsb,bcd3	; si D7 de alphalsb = 0, suivant
		dec x
		dec x
		jp bcd8

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

bcd4		subi a,10
		ld unit,a
		inc diz			; alors incrementer les dizaines

bcd6		dec x
		ld a,diz
		add a,(x)
		ld diz,a		; aux dizaines...
		cpi a,10
		jrc bcd7		; debordement?
		subi a,10
		ld diz,a
		inc cent		; alors incrementer les centaines

bcd7		dec x
		ld a,cent
		add a,(x)
		ld cent,a		; aux centaines.

bcd8		ld a,x
		cpi a, decimal.d	; fin de la table?
		jrz bcd9
		ld a,alphalsb		; non: decalage a gauche
		sla a			; du nombre a convertir
		ld alphalsb,a
		dec x			; prochaine valeur de la table
		jp bcd2			; bouclage

bcd9		ret			; fin de conversion

;gestion de l'affichage LCD
;==========================

gestion		ld a,cent		; eteindre afficheur
		jrnz gestion1		; si valeur nulle
		ldi cent,0Fh
		ld a,diz
		jrnz gestion1
		ldi diz,0Fh

gestion1	ld a,cent		; charger le driver des centaines
		add a, polar
		ld dra,a
		set 6,dra
		res 6,dra

		ld a,diz		; charger le driver des dizaines
		add a, polar
		ld dra,a
		set 5,dra
		res 5,dra

		ld a,unit		; charger le driver des unites
		add a, polar
		ld dra,a
		set 4,dra
		res 4,dra

		ld a, polar		; inverser la polarite
		addi a, 80h		; de l'afficheur
		ld polar, a		; panneau arriere (back plane)

gestion2	call tempo		; tempo d'affichage

gestion3	ret

;tempo de phase du LCD

tempo		ldi y,05h		; a 6.144MHz:
tempo1		ldi v,0D0h		; 6*200*6
		ldi wdr,watch
tempo2		dec v			; =7200 cycles
		jrnz tempo2		; a 2 microS=
		dec y			; 14.4ms
		jrnz tempo1		; environ
		ret

;Interruption du CAN et demarrage
;================================

		.org 0FF0h

adc		reti

		.org 0FFCh

nmi		reti

		.org 0FFEh

res		jp reset

