;giokino.asm ;Stefano Salvi - 17/8/02 ; ;Questo programma e' un gioco che aumenta il punteggio nei led gialli ogni volta ;che si preme ;il pulsante e e' contemporaneamente acceso l'ultimo led rosso. Quando vinco ;lampeggiano tutti i led per 3 volte. ;Imposto la porta di controllo con la porta a e c bassa di output e c alta di ;input. ;inizializzo un contatore e guardo se quando premo il tasto il mio contatore e' a ;p1 e allora faccio illuminare 3 volte i led e intanto faccio incrementare il ;contatore giallo. ; ; I LED rossi sono connessi alla porta A del PPI. ; I LED gialli sono connessi alla porta C 0..3 del PPI ; I Bottoni verdi sono connessi alla porta C 4..7 del PPI ; Il port A del PPI e' all'indirizzo 0FA00H nella memoria XDATA. ; Il port C del PPI e' all'indirizzo 0FA02H nella memoria XDATA. ; Il port di Controllo del PPI e' all'indirizzo 0FA03H nella memoria XDATA. ; La programmazione del PPI sara' la seguente: ; 1xxx xxxx Programmo port ; x00x xxxx Port A -> modo 0 ; xxx0 xxxx Port A -> output ; xxxx 1xxx Port C Hi -> input ; xxxx x0xx Port B -> modo 0 ; xxxx xx1x Port B -> input ; xxxx xxx0 Port C Lo -> output ; --------- ; 1000 1010 ; .org 8050h ; Definisco alcune costanti utili: .equ PPIPORTA, 0FA00h ; Port A del PPI .equ PPIPORTC, 0FA02h ; Port C del PPI .equ PPICTL, 0FA03h ; Port di controllo del PPI .equ novince, 0 ; Variabile BIT che indica stato vecchio tasto sjmp main ; salta le subroutine e va al programma principale ;----------------------- routine di ritardo ------------------------------------ ; Ritardo di circa 0,2 secondi ; Con il quarzo a 1059200 Hz, l'8051 esegue 921600 cicli al secondo ; Se voglio 5 lampeggi al secondo, devo avere un ritardo di 184320 cicli. ; Ipotizzando di avere un' 'operazione base' di 4 cicli, 240 ripetizioni di ; questa operazione porteranno ad impiegare 240*4 = 960 cicli totali. ; Se ora ripeteremo qesto ritardo base per 192 volte, otterremo 960*192=184320 ; cicli int otale (non contando i 4 cicli aggiuntivi per ripetere il ritardo ; base, pari a 192*4=768) ; Ingresso: ; nessuno ; Uscita: ; nessuna ; Modifica: ; r0,r1 delay: mov R1,#192 ; 192 ripetizioni di un ritardo base lp2: ; Ciclo Esterno mov R0,#240 ; 200 ripetizioni di piccolo ritardo (2 nop) lp3: ; Ciclo Interno nop ; operazione nulla - circa un micorsecondo (uS) djnz R0,lp3 ; Ripete 'nop' (ci mette circa altri 2 uS) djnz R1,lp2 ; ripete il ritardo precedente (200 * 3 -> 600 uS) ; ret ;--------------------------------------------------------------------------- ; main program ;--------------------------------------------------------------------------- main: ;----------------------inizializzazioni---------------------------------------- mov sp,#8Fh ; Imposta lo stack per la chiamata a 'delay' ; Programmo port, Port A -> modo 0, Port A -> output, Port C Hi -> input, ; Port B -> modo 0, Port B -> input, Port C Lo -> output mov a,#10001010b ;imposto porta di controllo mov dptr,#PPICTL movx @dptr,a mov a,#1111b ;imposta porta led gialli-verdi mov dptr,#PPIPORTC movx @dptr,a mov r2,#01111111b ; Configurazione dei LED - 0 -> Acceso, 1 -> Spento mov dptr,#PPIPORTA ; Porta LED rossi mov a,r2 ; recupera configurazione LED movx @dptr,a ; La invia ai LED mov r5,#0 ; Contatore Punteggi ; mainlp: ; ; Attende il ritardo necessario ed aggiorna la configurazione dei LED ; acall delay ; chiama routine di ritardo ; ; Elaborazione alla fine, prima di cambiare visualizzazione ; ; Test del tasto di 'reset Gioco' ; mov dptr,#PPIPORTC ; bit 4-7 -> tasti movx a,@dptr ; Legge porta jnb acc.6,main ; Settimo tasto premuto -> reset gioco ; ; ;---------------------------------------------------------------------------- ; Il tasto deve essere premuto quando l'ultimo LED rosso e' acceso. ; Per evitare che, tenendo il tasto premuto, si vinca, quando e' acceso il ; penultimo LED rosso, controllo che il tasto sia rialsciato. ; Solo se il tasto era rilasciato, trovandolo premuto con l'ultimo LED, conto il punto ; cjne r2,#11111101b,testLed7 ; ; E' acceso il penultimo LED: ; Se il tasto e' gia' premuto, setta il FLAG ; mov dptr,#PPIPORTC ; porta pulsanti movx a,@dptr ; legge il pulsante clr novince ; azzera il 'flag' jb acc.7,fineMain ; bit7=1 -> pulsante rialsciato setb novince ; pulsante gia premuto -> setto flag sjmp fineMain ; prosegue ; testLed7: cjne r2,#11111110b,fineMain ; ; E' acceso l'ultimo LED ; jb novince,fineMain; pulsante premuto da prima: risultato non valido mov dptr,#PPIPORTC ; porta pulsanti movx a,@dptr ; legge il pulsante jb acc.7,fineMain ; Pulsante del gioco non premuto, nessun punto ; ; pulsante premuto -> vincita!! ; inc r5 ; contatore vittorie mov dptr,#PPIPORTC ; Port LED gialli mov a,r5 ; copia la configurazione anl a,#0fh ; Elimina i bit in eccesso (4 LED) cpl a ; Inverte configurazione (0 -> Acceso, 1 -> spento) movx @dptr,a ; Manda sui LED mov dptr,#PPIPORTA ; porta led rossi mov a,#00000000 mov r3,#6 ; sei inversioni -> tre lampeggi vinciloop: movx @dptr,a ; manda codice sui LED acall delay ; Pausa per visualizzare i LED cpl a ; cambia da acceso (0) a spento (1) o viceversa tutti i LED djnz r3,vinciloop ; ; Fine codice vincita ; fineMain: ; ; Calcola la nuova configurazione e la visualizza ; mov dptr,#PPIPORTA ; porta led rossi mov a,r2 ; configurazione memorizzata rr a ; Ruota la configurazione (Bit 0 va in Bit 7) movx @dptr,a ; la manda sui LED mov r2,a ; Rimette nel registro la configurazione aggiornata ; sjmp mainlp ; loop .end