.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