Logo del sito i2viu

TASTO BUG SOFT ST6210
by Vittorio Crapella - i2viu

 

   	.title  "BUG-SOFT"  ;01/11/1995 by i2viu Op. Vittorio Crapella Sondrio
			    ;
	.vers   "ST62E10"       
        .w_on
    
;****************************************************************************
;*                       VARIABILI DEL MICRO                                *
;****************************************************************************

a       .def    0ffh    ;ACCUMULATOR (REGISTRO ACCUMULATORE)
x       .def    080h    ;X REGISTER  (REGISTRO X)
y       .def    081h    ;Y REGISTER  (REGISTRO Y)
v       .def    082h    ;V REGISTER  (REGISTRO V)
w       .def    083h    ;W REGISTER  (REGISTRO W)


;              DEFINIZIONE DEI REGISTRI DELLE PORTE
;              ------------------------------------

port_a  .def    0c0h    ;PORT A DATA REGISTER
port_b  .def    0c1h    ;PORT B DATA REGISTER
port_c  .def    0c2h    ;PORT C DATA REGISTER
pdir_a  .def    0c4h    ;PORT A DIRECTION REGISTER  (0=Input   1=Output)
pdir_b  .def    0c5h    ;PORT B DIRECTION REGISTER
pdir_c  .def    0c6h    ;PORT C DIRECTION REGISTER
popt_a  .def    0cch    ;PORT A OPTION REGISTER
popt_b  .def    0cdh    ;PORT B OPTION REGISTER
popt_c  .def    0ceh    ;PORT C OPTION REGISTER


;               DEFINIZIONE DEL REGISTRO DEGLI INTERRUPT
;               ----------------------------------------

ior     .def    0c8h    ;INTERRUPT OPTION REGISTER.


;               DEFINIZIONE DEL REGISTRO PER IL CONVERTITORE A/D
;               ------------------------------------------------

addr    .def    0d0h    ;A/D DATA REGISTER (REGISTRO DATI DEL CONVERTITORE)
adcr    .def    0d1h    ;A/D CONTROL REGISTER (REGISTRO DI CONTROLLO)


;               DEFINIZIONE DEI REGISTRI DEL TIMER
;               ----------------------------------

psc     .def    0d2h    ;TIMER PRESCALER REGISTER (REGISTRO DEL PRESCALER)
tcr     .def    0d3h    ;TIMER DATA REGISTER (REGISTRO DATI)
tscr    .def    0d4h    ;TIMER TSCR REGISTER ( REGISTRO PER IL CONTROLLO
			;DELLO STATO DEL TIMER)


;               DEFINIZIONE DEL REGISTRO PER IL WATCH-DOG
;               -----------------------------------------

wdog    .def    0d8h    ;WATCHDOG REGISTER


;              DEFINIZIONE DEL REGISTRO PER LO SPAZIO DATI ROM
;              -----------------------------------------------

drw     .def    0c9h    ;DATA ROM WINDOW REGISTER

;****************************************************************************
;*                         VARIABILI DEL PROGRAMMA                          *
;****************************************************************************


punto    .def    084h    ;flag di pigiata-esecuzione punto
linea    .def    085h    ;flag di pigiata-esecuzione punto
corto    .def    086h    ;durata punto
lungo    .def    087h    ;durata linea
pausa    .def    088h    ;durata spazio fra battute
mode     .def    089h    ;bit0=memoria punto bit1=memoria linea  bit3=S.A.
medio    .def    08ah    ;punto+spazio diviso due = puntomedio
div	.def     08bh	;dividento per SUBB e risultato da SUBB
ratio	.def	 08ch	;massimo ratio 
test	.def	 08dh	;per sapere se ratio up o dw 1=up 0= dw
unita   .def	 08eh	
decine	.def	 08fh
rest	.def     090h	;resto div
tipo 	.def	 091h	;modo di operare 1-4  1=jambic 2=no mem punto 3=sq.
			;4= semi automatico
delai   .def     092h   ;valore per routines delay
nrcar   .def     093h   ;numero dei caratteri della tabella per casulai
tipcar  .def     094h	;tipo di casuale  0-5 lett,num,acc,punteg,let-num,comp
car     .def     095h   ;numero car gen (5)
tab	.def	 096h	;nr dove parte la tabella per ricerca caratteri
casu    .def     097h	;pari a 5x nrcar
ratiop  .def     098h   ;viene depositato ratio punto minore di 90
ratiol  .def     099h   ;viene depositato ratio linea maggiore di 90
;massimo fino a  0BFh   ;ultima cella ram disponibile
;****************************************************************************
;*                         SETTAGGIO INIZIALE                               *
;****************************************************************************


;             INIZIO DEL PROGRAMMA
;             --------------------
	.org    0880h   

inizio                  ;  INIZIALIZZAZIONE DELLE PERIFERICHE


	ldi     wdog,0ffh       ; RICARICA IL WATCH DOG

;      SETTAGGIO DELLA PORTA "A" COME INPUT PULL-UP             
;      ---------------------------------------------              
	ldi     port_a,00000000b
	ldi     pdir_a,11110000b  ;CON 0FFh SI SELEZIONA L'USCITA PUSH-PULL
	ldi     popt_a,11110000b  ;    000               INPUT    PULL-UP
				  ;da A0 a A3 mai come A/D
	
;      SETTAGGIO DELLA PORTA "B" COME OUTPUT   PUSH-PULL   10mA
;      --------------------------------------------
	ldi     port_b,01111111b  ;setta a 1 alla partenza gli out
	ldi     pdir_b,01111111b  ;CON 0h SI SELEZIONA L'INPUT PULL-UP
	ldi     popt_b,01111111b  

	ldi     adcr,0          ;DISABLE A/D INTERRUPT
	ldi     tscr,0          ;DISABLE TIMER INTERRUPT
	ldi     ior,0           ;DISABLE ALL INTERRUPT

	reti                    ;RIPRISTINA I FLAG PRINCIPALI


	jp      main            ;SALTA AL PROGRAMMA PRINCIPALE


;****************************************************************************
;*                       SUBRINE DI INTERRUPT                            *
;****************************************************************************

ad_int                  ;INTERRUPT DEL CONVERTITORE A/D
	reti

tim_int                 ;INTERRUPT DEL TIMER
	ldi wdog,255
	ldi tcr,110
	ldi tscr,01011010b
	jrs 2,port_b,zero
	set 2,port_b		;mette alto pin 2 porta_b
	reti
zero	res 2,port_b		;mette basso pin 2 porta_b
	reti

BC_int                  ;INTERRUPT DELLE PORTE A e B
	reti

A_int                   ;INTERRUPT DELLA PORTA A
	reti

nmi_int                 ;INTERRUPT NON MASCHERABILE
	reti


;****************************************************************************
;*                         SUBROUTINE                                       *
;****************************************************************************
delay 	ld x,a
	ld a,delai
	ld y,a   
	ld a,x
	ldi wdog,255
rep	dec y
	jrnz rep
	ret


tasti   ldi wdog,0feh 
	jrs 0,port_a,t2    ;se non pigio pala punti vai a t2
	jrs 1,port_a,t1    ;se non pigio pala linee vai a t1
	
	jrs 0,linea,l1p2  	 ;di qui se pigio entrambe
	jrs 1,linea,l1p2
			   	;se la linea e` gia` pigiata (non=0) salta
	ldi punto,1	   	;altrimenti prima punto
	ldi linea,2	   	;poi linea
ritor	ret		   	;ritorna
l1p2    jrs 0,punto,ritor
	jrs 1,punto,ritor
	ldi linea,1	   	;se il punto non e` finito allora 
	ldi punto,2	   	;allora linea=1 e punto=2
	ret
t1      			;arrivo qui se pigio punti e non linee
	jrs 0,punto,ritorn	;se punto non e` 0 salta
	jrs 1, punto,ritorn
	jrs 0,port_a,ritorn	;se non pigio punti salta
	jrs 0,linea,p2		;se linea non e` 0 salta a mettere punto=2
	ldi punto,1		;altrimenti punto=1
ritorn	ret
		
p2      jrr 0,mode,ritorn	;verifica il MODO se con o senza memoria
	ldi punto,2		;se con mem allora punto=2
	ret
t2      			;arriva qui se non pigio punti
				;verifica se linea e` gia `pigiata
	jrs 0,linea,ritorn	;se lo e` gia ritorna
	jrs 1,linea,ritorn
	jrs 1,port_a,ritorn	;pure se non pigio linee salta
	jrs 0,punto,l2		;se pigio linea  verfica punto
				;se non e` 0 salta a mettere linea=2
	ldi linea,1		;altrimenti linea=1
	ret
l2      jrr 1,mode,ritorn	;verifica il MODO se con o senza memoria
	ldi linea,2		;se con mem allora linea=2
	ret

out	jrr 7,port_b,out	;se pigiato FUNZ non va in TX
	set  1,port_b    	 ;ini cw out  livello alto
out1	set 4,ior
	ldi tcr,110
	ldi tscr,01011010b
suono  	call delay
	ldi	wdog,255
	jrr	2,mode,lines
	clr	linea
	jrs	0,port_a,suon1
	ldi	punto,1
suon1	jrr 1,port_a,suono	;se e` S. A. e pigio pala linee continua suono
	jp	cade
lines	call 	tasti
cade	call	delay
	dec a
	jrz suo
	jp suono
suo	res 1,port_b     		;fine cw out livello basso
	res 4,ior
	res 2,port_b
	ret


velo	ldi drw,alfa.w			;VELOCITA`
	ldi tab,90		;punta ai numeri in TAB
	jrr 6,delai,div4	;se none QRS salta
	ldi div,2		;se QRS divide solo per 2
	jp ldmed
div4	ldi div,4
ldmed	ld a,medio
	call subb
	ldi a,230
	call subb		;torna con a=wpm
	cpi a,10
	jrc cacw		;se a < di dieci allora solo un numero
	ldi div,10
	call subb		;torna con a=decine di wpm
	call cw
	call spclu		;spazia fra i num. wpm
	ld a,rest  		;punta ai numeri  rest=unita  wpm
cacw	call cw
	call spclu
	call spclu
	call spclu
	ldi a,11111011b		;W
	call cw2
	call spclu
	ldi a,11110110b		;P
	call cw2
	call spclu
	ldi a,00000011b		;M
	call cw2
	ret


comandi	ldi wdog,0feh		;COMANDI
	jrr 0,port_a,velo
	jrs 7,port_b,comandi
type	ldi drw,let.w
	ldi tab,40h
	ld a,tipo
	cpi a,1
	jrnz lop2
	ldi mode,3		;jambic
	call cw			; J
	call spclu
	ldi a,11111101b		; A
	call cw2
lop2	cpi a,2
	jrnz lop3
	ldi  mode,2		;no memoria punto
	call cw			; N
	call spclu
	ldi a,00000011b		; M
	call cw2
lop3	cpi a,3
	jrnz lop4
	clr mode		;mode=0   = squizze
	call cw			; S
	call spclu
	ldi a,00001101b		; Q
	call cw2
lop4	cpi a,4
	jrnz usc
	ldi mode,5		;semi automatico
	call cw			; S
	call spclu
	ldi a,11111101b		; A
	call cw2
usc	ldi wdog,0feh
	jrr 0,port_a,casual
	jrr 7,port_b,inctip
	jrs 1,port_a,usc
	ret
inctip	inc tipo
	ld a,tipo
	cpi a,6
	jrnz oltre
	ldi tipo,1
oltre	jp type

casual	    			;GENERAZIONE CARATTERI CASUALI
	
	ldi car,5
	ldi drw,alfa.w		;finestra dei caratteri
casual1	ld a,test		;prende il valore test (casuale) per 
	ldi wdog,255		;puntare a un carattere
cpia	cp a,nrcar		;verifica se e compreso nelle 27 lettere
	jrc ldiw		
	sub a,nrcar		;se maggiore sottrae 27 fino a renderlo
	jp cpia			;minore
ldiw	ld y,a			;salva moment. a in y
	rlc a		;ruota a per rendere casuale
	sub a,casu      ;sottrae pure casu  sempre per casuale
	add a,car		;aggiunge per come sopra
	inc test
	ld test,a		;e lo mette in test per utilizzare la prox
	ld a,y			;recupera a da y
	call cw			;va a prendere il car corrispondente e poi cw
	call spclu		;spazio fra lettere
	dec car			;conta i car generati (gruppi di 5)
	jrnz altrca		;se non e` zero salta
	ld a,test		;altrimenti per cambiare il casuale complememta
	rlc a
	ld test,a		;e rimette in test per usare la prox
	ldi car,5		;rimette numero caratteri 5
	call spclu		;doppio spazio fra gruppo e gruppo
	call spclu
	call anadig		;aggiorna velocita`
altrca	
	jrr 7,port_b,nctip	;cambia tipo di casuale
	jrr 1,port_a,nocas	;se pigio pala linee esce da casuale
	inc casu  		;conta quante lettere generate
	ld a,nrcar
	cp a,casu
	jrc jpca		;se non ancora salta altrimenti
	rlc a
	ld test,a
	add a,car
	sla a
	ld casu,a
jpca	jp casual1		;ricomincia a gen casuale
nocas	ret

nctip	inc tipcar		;cambia tipo di casuali
	ld a,tipcar
	cpi a,1		;NUMERI
	jrnz due_		;se non e` 1 salta
	ldi tab,90		;punta a 40h+27 dove comincia numeri
	ldi nrcar,10		;quantita` car numeri
due_	cpi a,2		;ACCENTATE
	jrnz tre_
	ldi tab,100		;punta a 40h+27+10
	ldi nrcar,7		;quantita` accentate
tre_	cpi a,3		;PUNTEGGIATURA
	jrnz qua_
	ldi tab,107		;punta a 40h+27+10+7
	ldi nrcar,14		;quantita` puntegg.
qua_	cpi a,4		;LETTERE E NUMERI
	jrnz cin_
	ldi tab,40h		;punta inizio tabella alfabeto
	ldi nrcar,36		;quantita` lett. e num.
cin_	cpi a,5		;COMPLETO
	jrnz zero_
	ldi tab,40h
	ldi nrcar,57		;totale caratteri
zero_	cpi a,6
	jrnz okas
	ldi tipcar,0		;SOLO LETTERE
	ldi tab,40h
	ldi nrcar,26
okas	ldi wdog,255
	jrr 7,port_b,okas
	jp casual

spclu 	ld a,lungo		;SPAZIO x CASUALE
space	call delay
	call delay
	dec a 
	jrnz space
	ret

subb				;DIVISIONE si entra con dividendo in DIV
				;ritorna con DIV= a/DIV
	clr x			;x=0
sub_	sub a,div
	inc x
	ldi wdog,255
	cp a,div
	jrnc sub_
	ld rest,a		;resto
	ld a,x
	ld div,a		;risultato
	ret

cw				;RISPONDE IN CW per wpm e comandi
				;a= nr della tabella da prendere
	ldi wdog,0feh
	add a,tab
	ld x,a
	ld a,(x)		;punta a tab. numeri
cw2	ldi w,8
	rlc a
	jrc cerca0		;se cy=1 allora cerca 0
cerca1  dec w
	ld v,a
	rlc a
	jrnc cerca1
	inc casu		;per casuale
	jp cw_
cerca0	dec w
	ld v,a
	rlc a
	inc test		;per casuale
	jrc cerca0
cw_	ld a,v
	rlc a
	jrnc cort
	ld v,a
	ld a,lungo
	jp calout
cort	ld v,a
	ld a,corto
calout  call out
	ld a,pausa
	call space
	dec w
	jrz fine
	jp cw_
fine	ldi a,0ffh	;in comandi non compara dall' 1/4 e arriva a USC
	ret

;CONVERTE ANALOGICO/DIGITALE PER VELOCITA`
anadig  res 6,pdir_b           ;mette a 0 bit 6 per impostare A/D pin9
	ldi adcr,00110000b     ;attiva A/D
attendi jrr 6,adcr,attendi
	ld a,addr		;mette in a valore della conversione
	set 6,pdir_b		;disattiva A/D del pin 9
	ldi div,2		;trova val di un punto
	call subb
	ld pausa,a
	ld medio,a
	ld a,ratiop
	call ratok
	ld a,ratiol
	
ratok
	ldi div,10		;prepara a dividere x 10
	call subb		; ratio/10
	ld v,a			;salva a in v=ratio/10
	ld a,rest		;verifica se >2
	cpi a,3
	jrc minor3		;se minore 3 salta
        ldi div,3
	call subb		;divide rest/3
	ld y,a			;salva a in y=rest/3
minor3	ld a,v			; riprende ratio/10
	cpi a,9			;ver. se a < 9 salta e` ratio punto
	jrc medx
	ld a,medio
	add a,medio		;in a= linea
	add a,medio
	ld w,a			;salva in w=linea
	jp esegui
medx	ld a,medio
esegui  clr unita
	ldi div,10		;se ratiolinee decine=lungo/10
	call subb
	ld decine,a		;salva a in decine=medio/10
	ld a,rest
	cpi a,2
	jrc minor2		;se <2 salta
	ldi div,2
	call subb
	ld unita,a		;unita=rest/2
minor2	ld a,v			;prende ratio/10
	cpi a,9
	jrnc suba9		;salta se =>9 cioe` ratio linea
	jp rat_cort		;altrimenti e` ratio punto
suba9	cpi a,10
	jrnc subia
	ret
subia	subi a,9		;rende ratio ok per calcoli
	cpi a,2			;non va meno di 2
	jrnc calxa		;se e`>2 salta
	ldi a,2
calxa   ld v,a
	call xadd		;v=decine*v =A*B
	ld a,w			;carica a lungo
	ldi div,2		;prende 1/2 linea
	call subb
	add a,v			;1/2linea+(A*B) 
	add a,y			;+R2
	add a,unita		;+R1 = nuovo lungo (durata linea)
	cpi a,255
	jrc okl			;se minore 255 salta
	ldi a,255		
okl	ld lungo,a
	ret

rat_cort call xadd
	ld a,medio
	ldi div,2		;1/2 medio=1/2 punto
	call subb
	add a,v			;+A*B
	add a,y			;+R2
	add a,unita		;+R1 =nuovo corto (durata punto)
	cpi a,12
	jrnc okp		;se maggiore salta
	ldi a,12
okp	ld corto,a
	ret
				;MOLTIPLICAZIONE  decine x v
xadd	clr a
adda	add a,decine
	ldi wdog,255
	dec v
	jrnz adda
	ld v,a			;salva in v=A*B
	ret

rat_da				;LEGGE RATIO arriva da LeP + FUNZ.
	res 5,pdir_b		;bit 5 pin 10 a 0 per A/D
	ldi adcr,00110000b	;attivo A/D
atteso	jrr 6,adcr,atteso	;aspetto conversione
	ld a,addr		;mette in a ratio
	set 5,pdir_b		;disattiva pin 5 per A/D
	cpi a,90
	jrc rat_pu		;se a<90 e` ratio punto
	ld ratiol,a		;mette in ratiol(inea)
	call ratok
	ret
rat_pu  ld ratiop,a
	call ratok
	ret

	.block 64-$%64
let	.byte   11110111b
	.byte	11110111b		;ja  jambic
	.byte	00000010b		;nm  no mem punto
	.byte	11111000b		;sq  squezze	
	.byte	11111000b		;sa  semi automatico

	.block 64-$%64
alfa    .byte   11111101b	;a
	.byte	00001000b	;b
	.byte   00001010b	;c
	.byte   00000100b	;d
	.byte	11111110b	;e
	.byte   11110010b	;f
	.byte   00000110b	;g
	.byte   11110000b	;h
	.byte   11111100b	;i
	.byte   11110111b	;j
	.byte   00000101b	;k
	.byte   11110100b	;l
	.byte   00000011b	;m
	.byte   00000010b	;n 
	.byte   00000111b	;o
	.byte   11110110b	;p
	.byte   00001101b	;q
	.byte   11111010b	;r
	.byte   11111000b	;s
	.byte   00000001b	;t
	.byte   11111001b	;u
	.byte   11110001b	;v
	.byte   00001100b	;z
	.byte   00001001b	;x
	.byte   00001011b	;y
	.byte   11111011b	;w

 	.byte	00011111b		;=0
	.byte  	11101111b		;=1
	.byte  	11100111b		;=2
	.byte	11100011b		;=3
	.byte	11100001b		;=4
	.byte	11100000b		;=5
	.byte	00010000b		;=6
	.byte	00011000b		;=7
	.byte   00011100b		;=8
	.byte	00011110b		;=9	
						
	.byte	11110101b	;
	.byte	00001110b	;
	.byte   11110011b	;u`
	.byte   11101101b	;a`
	.byte   11100100b	;
	.byte   00010100b	;
	.byte   00011011b	;

	.byte   11001100b	;?	
	.byte	00010010b	;/
	.byte   00010110b	;)
	.byte   00101101b	;(
	.byte   11010101b	;.
	.byte   11101110b	;'
	.byte   00110011b	;,
	.byte   00010001b	;bt
	.byte   00111000b	;:
	.byte   11001101b	;sottolineato
	.byte	00100001b	;-
	.byte	00010010b	;"
	.byte   00101010b	;;
	.byte   11101010b	;ar
;***************************************************************************
;*                         PROGRAMMA PRINCIPALE                            *
;***************************************************************************

main   	ldi tab,40h		;prepara per casuale tipo 0=solo lettere
	ldi nrcar,26
	clr tipcar
	ldi tipo,1
	ldi mode,3
	ldi delai,50		;parte qrq
	ldi ratiop,48		;parte con un ratio appena sotto il 50 
	ldi ratiol,145		;parte con linea appena poco piu` lunga
	call anadig		;legge potenziometro velocita`
paus   
	ld a,pausa
        call space
	call delay
taa
	jrs 0,punto,punta	;salta a punta se punto=1
	jrs 0,linea,line	;salta se linea non e` 0
	jrs 1,punto,punta	;salta se punto=2
	jrs 1,linea,line
	call tasti
	call anadig		;aggiorna lettura pot. VELO. 
	jrs 7,port_b,taa
asp	jrr 0,port_a,qrs
	jrr 1,port_a,com2
	ldi wdog,255
	jp asp
qrs	ld a,delai
	cpi a,100
	jrz qrq
	ldi delai,100
	jp paus
qrq	ldi delai,50
	jp paus
com2	
	call comandi
	clr punto		;azzera punto e linea
	clr linea
	jp paus
line    ld a,lungo
	clr tab			;per ricordare in OUT che e` linea
	call out
	clr linea
	jrs 7,port_b,paus
	ld a,punto
	cpi a,0
	jrnz jpau
; 	call decpu			;INCREMENTA VELOCITA`
;	call decsp
;	call decli
	jp paus
jpau	call rat_da         	;call rati
	jp paus
punta   ld a,corto
	ldi tab,0ffh		;per ricordare in OUT che e` punto
	call out
	clr punto
	jrs 7,port_b,paus
	ld a,linea
	cpi a,0
	jrnz jpaus
;	call incpu		;DECREMENTA LA VELOCITA`
;	call incsp
;	call incli
	jp paus
jpaus  	call rat_da		;aggiorna RATIO punto o linea
	jp paus

;****************************************************************************
;*                     VETTORI DI INTERRUPTS                                *
;****************************************************************************

	.org    0ff0h
	jp      ad_int  ;INTERRUPT DEL CONV. A/D     vector #4
	jp      tim_int ;INTERRUPT DEL TIMER         vector #3
	jp      BC_int  ;INTERRUPT PORTE A e B       vector #2
	jp      A_int   ;INTERRUPT PORTA A           vector #1
	.org    0ffch
	jp      nmi_int ;INTERRUPT NON MASCHERABILE  vector #0
	jp      inizio  ;INTERRUZIONE PER IL SETTAGGIO INIZIALE

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

	.end                    ; Termine del programma





Disclaimer     INDEX             Torna indietro