; SMILENGHEADER ; COMMENT This is the Smile NG file header, do not modify! ; VERSION 1.0 ; PROC CALM ;-------------------------------------------------------------------------------+ ; | ; Petit programme qui affiche sur l'écran LCD ce qui est lu sur le port MUBUS | ; | ;-------------------------------------------------------------------------------+ .PROC z80 .BASE 10'16 jump start ; on va au début du programme ; Définition des constantes .BASE 10'2 ; ========================================= ; CONSTANTES LCD (instructions) ZERO = 0 FINIT = 00110000 ; Valeur d'initialisation FSET = 00111000 ; Function SET (8 bits, char 5x8 px) DISP = 00001100 ; Display ON, Cusror OFF, Blink OFF ; Pour avoir le curseur : DISP+1 CLRDSP = 00000001 ; Efface l'écran, remet à la position initiale EMSET = 00000110 ; Entry Mode Set (fin de l'initialisation) PAHAUT = 10000000 ; Page/rangée supérieure de l'écran PABAS = 11000000 ; Page/rangée inférieure de l'écran BUSY = 10000000 ; Masque pour vérifier l'état du flag busy (qui est sur D7) ; ========================================= .BASE 10'16 ; Adresses RAM Réservées pour l'OS le programme. ; Pages mémoires PAGE0 = 4100 PAGE1 = 4110 PAGE2 = 4120 PAGE3 = 4130 PAGE4 = 4140 PAGE5 = 4150 PAGE6 = 4160 PAGE7 = 4170 PAGE8 = 4180 PAGE9 = 4190 PAGEA = 41A0 PAGEB = 41B0 PAGEC = 41C0 PAGED = 41D0 PAGEE = 41E0 PAGEF = 41F0 ; ========================================= ; Adresses des périphériques ; Adresse MUBUS MUBWR = 0 MUBRD = 10 ; Adresses LCD LCDWRI = 40 LCDWRD = 41 LCDRDI = 42 LCDRDD = 43 ; Adresse du sommet de la pile du soft RAMTOP = 7FFF ;========================================= ; initialisation start: ;création de la pile au sommet de la RAM (évite des bugs avec l'utilisation de zones réservées dans la RAM) ioff ; désactive les interruptions move #RAMTOP,SP ; place le pointeur de pile au sommet de la ram im1 ; met le mode d'interruptions 1 debut: call initlcd ; Initialise l'écran ; message d'accueil move #LONG1,B ; longueur du message move #msg1,HL call wrstr ; on passe à la ligne call carret ; on écrit la 2è ligne du message d'accueil move #LONG2,B ; longueur du message move #msg2,HL call wrstr ; tempo pour lire le message move #0FF,A lect4: call attente dec A jump,ne lect4 move #0FF,A lect5: call attente dec A jump,ne lect5 move #0FF,A lect6: call attente dec A jump,ne lect6 call clrscr ; on écrit la valeur lue sur le port MUBUS move #LONG5,B ; longueur du message move #msg5,HL call wrstr call carret ; à la ligne ;traitement de la valeur lecture: move $MUBRD,A ; on stock la valeur des switches dans A move A,PAGE2 ; on stock dans la variable PAGE2 ;écriture sur le port MUBUS move PAGE2,HL move H,A move A,$MUBWR move L,A move A,$MUBWR+1 ;détermination de la valeur à afficher move PAGE2,A comp #10,A ; valeur inférieure à 10h ? jump,HS detnb ; non, on s'ocupe de faire un affichage propre jump affakespace ; oui on affiche detnb: ; on utilise le principe de masque pour garder la dizaine et l'unité séparées. move PAGE2,A .BASE 10'2 and #11110000,A ; on ne garde que les dizaines rr A rr A rr A rr A ; on place en unité move A,PAGE4 ; on sauve la variable .BASE 10'16 comp #0A,A ; valeur "numérique" ? jump,HS miseformed ; non on met en forme move PAGE4,A ; oui => on affiche. valeur lue add #30,A ; caractère ASCII move A,PAGE3 ; on sauve jump affnumd ; on affiche miseformed: move PAGE4,A add #37,A move A,PAGE3 ; on adapte pour avoir le A,B,C,D,E ou F affnumd: .BASE 10'2 move #11000011,A ; 2è ligne ; 4è colonne .BASE 10'16 move A,$LCDWRI call attente call attente move PAGE3,A ;dizaine move A,$LCDWRD call attente call attente move PAGE2,A .BASE 10'2 and #00001111,A ; on ne garde que lesunités move A,PAGE4 ; on sauve la variable .BASE 10'16 comp #0A,A ; valeur "numérique" ? jump,HS miseformeu ; non on met en forme move PAGE4,A ; oui => on affiche. valeur lue add #30,A ; caractère ASCII move A,PAGE3 ; on sauve jump affnumu ; on affiche miseformeu: move PAGE4,A add #37,A move A,PAGE3 ; on adapte pour avoir le A,B,C,D,E ou F affnumu: .BASE 10'2 move #11000100,A ; 2è ligne ;5è colonne .BASE 10'16 move A,$LCDWRI call attente call attente move PAGE3,A ;valeur lue transformée en ASCII move A,$LCDWRD call attente call attente ; on affiche le h de la base jump affh ; positionnement de la valeur à afficher affakespace: comp #0A,A ; valeur "numérique" ? jump,HS miseforme ; non on met en forme move PAGE2,A ; oui => on affiche. valeur lue add #30,A ; caractère ASCII move A,PAGE3 ; on sauve jump affnum ; on affiche miseforme: move PAGE2,A add #37,A move A,PAGE3 ; on adapte pour avoir le A,B,C,D,E ou F affnum: .BASE 10'2 move #11000011,A ; 2è ligne ; 4è colonne .BASE 10'16 move A,$LCDWRI call attente call attente move #20,A ;espace move A,$LCDWRD call attente call attente .BASE 10'2 move #11000100,A ; 2è ligne ;5è colonne .BASE 10'16 move A,$LCDWRI call attente call attente move PAGE3,A ;valeur lue transformée en ASCII move A,$LCDWRD call attente call attente affh: .BASE 10'2 move #11000101,A ; 2è ligne ; 6è colonne .BASE 10'16 move A,$LCDWRI call attente call attente move #68,A ;h (pour signifier valeur hexa) move A,$LCDWRD call attente call attente jump lecture ;et on boucle sans fin ;========================================= ;Initialisation de l'écran LCD initlcd: move #ZERO,A move A,$LCDWRI move #FSET,A move A,$LCDWRI call attente call attente call attente call attente call attente call attente call attente call attente call attente call attente move #FSET,A move A,$LCDWRI call attente call attente ;---------------------------------------------- move #FSET,A move A,$LCDWRI call attente call attente ;---------------------------------------------- move #FSET,A move A,$LCDWRI call attente call attente ;---------------------------------------------- move #DISP,A move A,$LCDWRI call attente call attente ;---------------------------------------------- move #CLRDSP,A move A,$LCDWRI call attente call attente ;---------------------------------------------- move #EMSET,A move A,$LCDWRI call attente call attente ;---------------------------------------------- move #PAHAUT,A move A,$LCDWRI call attente call attente ;---------------------------------------------- ; message de fin, le périphérique est correctement initialisé move #LONG3,B ; longueur du message move #msg3,HL call wrstr ; on passe à la ligne call carret ; on écrit la 2è ligne du message d'accueil move #LONG4,B ; longueur du message move #msg4,HL call wrstr ; tempo pour lire le message move #0FF,A lect1: call attente dec A jump,ne lect1 move #0FF,A lect2: call attente dec A jump,ne lect2 move #0FF,A lect3: call attente dec A jump,ne lect3 call clrscr ret ;========================================= ;========================================= ; ROUTINES LCD ;========================================= ; Lecture du bit busy ; ATTENTION ROUTINE BUGUEE !!!! ; Tant qu'il est à 1, le LCD n'est pas prêt, dès qu'il passe à 0, on peut continuer ; méthode la plus rapide pour perdre le moins de temps possible lors d'écriture waitlcd: push AF wlcd: move $LCDRDI,A and #BUSY,A ; si le BF est à 0, on peut écrire sinon on ne peut pas. jump,zc wlcd ; jump Zero Clear / si c'est à 0 c'est fini sinon on boucle pop AF ret ;========================================= ;========================================= ; écriture d'une chaîne de caractère sur le LCD ; entrée ; - Longueur de la chaine de caractères en B ; - Adresse du début de la chaine en HL ; sortie : - rien ; modifie: - A, B, HL wrstr: move {HL},A ; acquérir le byte move A,$LCDWRD ; sortie du caractère sur l'écran call attente call attente inc HL ; pointage sur le caractère suivant dec B jump,ne wrstr ; boucle jusqu'à ce que tous les caractères soient affichés ret ;========================================= ;========================================= ; écriture d'un caractère sur le LCD ; entrée ; - adresse où se trouve le caractère dans HL ; sortie : - rien ; modifie: - A, HL wrchr: call attente call attente move {HL},A move A,$LCDWRD ret ;========================================= ;========================================= ; lecture d'un caractère sur le LCD ; entrée ; - adresse où sera copié le caractère en HL ; - adresse écran où se trouve le chr dans B ; sortie : - le caractère est copié où pointe HL ; modifie: - A, HL rdchr: call attente call attente ; on pointe où on va lire sur l'écran push AF move B,A move A,$LCDWRI pop AF call attente call attente ; on lit et on copie move $LCDRDD,A move A,{HL} ret ;========================================= ;========================================= ; lecture d'une chaîne de caractères sur le LCD ; entrée ; - adresse où sera copié le caractère en HL ; - adresse écran où se trouve le début de la chaîne dans B ; - longueur de la chaîne de caractères dans C ; sortie : - la chaine est copiée à partir d'où pointe HL ; modifie: - A, C, HL rdstr: call attente call attente ; on pointe où on va lire sur l'écran push AF move B,A move A,$LCDWRI pop AF rdstr1$: call attente call attente ; on lit et on copie move $LCDRDD,A move A,{HL} inc HL dec C move C,A comp #1,A jump,ne rdstr1$ ret ;========================================= ;========================================= ;carriage return ; entrée ; - rien ; sortie : - rien ; modifie - rien carret: push AF move #PABAS,A move A,$LCDWRI pop AF call attente call attente ret ;========================================= ;========================================= ;Clrear Screen : efface l'écran et repositionne au départ ; entrée : - rien ; sortie : - rien ; modifie : - rien clrscr: push AF move #CLRDSP,A move A,$LCDWRI pop AF call attente call attente ret ;========================================= ;========================================= ;Boucle d'attente attente: push AF move #0FF,A a$: dec A jump,ne a$ pop AF ret ;========================================= ;========================================= ; messages à afficher ; message d'accueil ; page du haut msg1: .ascii "- MUBUS READER -" msg1fin: nop LONG1 = msg1fin-msg1 ; Longuieur de la chaine de caractères ; page du bas msg2: .ascii " Version 0.22 " msg2fin: nop LONG2 = msg2fin-msg2-1 msg3: .ascii "LCD display" msg3fin: nop LONG3 = msg3fin-msg3 msg4: .ascii "ready!" msg4fin: nop LONG4 = msg4fin-msg4 msg5: .ascii "Value read :" msg5fin: nop LONG5 = msg5fin-msg5