PAGE 66,132 TITLE** PROGRAMMA di GESTIONE di programmi ASSEMBLER tipo COM (marzo 2003) SUBTTL ** TUTORIAL ASSEMBLY -- www.giobe2000.it -- by ing. Giorgio OBER ;/---------------------------------------------------------------------------\ ;| NOME : EditLCD2 | ;| AUTORE : Giorgio OBER | ;| VERSIONE 2 : marzo 2003 | ;| /----------\ /-----------------------------------------------------------\| ;| | | |Questa versione di "Edit_LCD" Š adatta ad ogni modello di|| ;| | VARIANTE | |Display a due linee, da 16, 20, 24, 32 o 40 caratteri per|| ;| | | |linea; inoltre gestisce il Visualizzatore a Video in modo|| ;| | | |dinamico, ricostruendone la posizione a video a partire|| ;| | | |dalle coordinate rigaIni,colnIni, riferite all'angolo in|| ;| | | |alto a sinistra dentro l'area del Visualizzatore destinata|| ;| | | |all'acquisizione dei caratteri, e prefissate nella zona|| ;| | | |delle COSTANTI DEFINITE PER IL PROGRAMMA (qui sotto). || ;| \----------/ \-----------------------------------------------------------/| ;| DESCRIZIONE: Programma per il collaudo dell'Interfaccia Software/Hardware| ;| di un Modulo LCD collegato su porta parallela LPT1. | ;| Si tratta di un vero e proprio "Editor" per Display LCD, in| ;| grado di accettare qualunque carattere Ascii e di gestire| ;| i tasti di movimento (le frecce , PgUp, PgDn, Home e End)| ;| per spostare il cursore senza scrivere, e quelli di controllo| ;| come Invio (va a capo linea) e BackSpace (cancella indietro).| ;| consente di commutare il controllo da 16 a 40 caratteri| ;| per riga, e cancella tutto il Display. | ;| Nella visualizzazione a Video sono presenti accorgimenti in| ;| grado di modificare la dimensione standard del Cursore, per| ;| favorire la migliore resa grafica. | ;| /----------\ -------------------------------------------------------------| ;| | | Se si lavora con i Sistemi Operativi Win2000, Win NT o WinXP | ;| | NB !! | bisogna prima installare il Driver Configura_LPT1; scaricalo | ;| | | a: http://www.giobe2000.it/consigli/Scarica_VediLPT_XP.htm | ;| *----------* -------------------------------------------------------------| ;| | | Se si lavora con i Sistemi Operativi Win2000, Win NT o WinXP | ;| | NB !! | la SHELL DOS deve essere a "Pieno Schermo" (l'esecuzione in | ;| | | "finestra DOS" non produce effetto sul Display LCD) | ;| *----------* -------------------------------------------------------------| ;| | | In ogni caso PRIMA DI OGNI SESSIONE DOS Š necessario eseguire| ;| | NB !! | il programma Config_LPT1.EXE in ambiente Windows per attivare| ;| | | la visibilit… dei driver installati con Configura_LPT1 !!!!! | ;| \----------/ -------------------------------------------------------------| ;\---------------------------------------------------------------------------/ ;/---------------------------------------------------------------------------\ ;| Collegamenti tra Porta Parallela LPT1 e MODULO Visualizzatore LCD | ;*---------------------------------------------------------------------------* ;| (378H)out/bit7 DIRETTO - pin09/PORTA PARALLELA --pin14/LCD Dato7 | ;| (378H)out/bit6 DIRETTO - pin08/PORTA PARALLELA --pin13/LCD Dato6 | ;| (378H)out/bit5 DIRETTO - pin07/PORTA PARALLELA --pin12/LCD Dato5 | ;| (378H)out/bit4 DIRETTO - pin06/PORTA PARALLELA --pin11/LCD Dato4 | ;| pin10/LCD n.c. | ;| pin09/LCD n.c. | ;| pin08/LCD n.c. | ;| pin07/LCD n.c. | ;| (37AH)out/bit0 NEGATO - pin01/PORTA PARALLELA --pin05/LCD R/W | ;| (37AH)out/bit3 NEGATO - pin17/PORTA PARALLELA --pin06/LCD E | ;| (37AH)out/bit2 DIRETTO - pin16/PORTA PARALLELA --pin04/LCD RS | ;| GND - pin18/PORTA PARALLELA -*pin03/LCD GND | ;| | pin02/LCD Vcc +5V | ;| \pin01/LCD GND | ;\---------------------------------------------------------------------------/ ; COSTANTI DEFINITE PER IL PROGRAMMA: rigaIni EQU 13 ; Coordinate dell'angolo in alto a sinistra del colnIni EQU 28 ; Visualizzatore a Video (dentro la cornice) ESC_ EQU 1BH ; Codice Ascii per il tasto Invio EQU 0DH ; BackSp EQU 08H ; Codici di protocollo per la gestione Frec_Su EQU 48H ; del Visualizzatore LCD Frec_Giu EQU 50H ; Frec_Dx EQU 4DH ; Frec_Sn EQU 4BH ; Home EQU 47H ; PgUp EQU 49H ; /-[NB:]-------------------------------\ PgDn EQU 51H ; |esclusi e | End_Fine EQU 4FH ; |sono tutti Tasti Funzionali, cioŠ | Del_Canc EQU 53H ; |caratterizzati da codice Ascii = 00H | F1_ EQU 3BH ; \-------------------------------------/ F2_ EQU 3CH ; ; MACRO UTILIZZATE DAL PROGRAMMA: include c:\arch-lab\bin\GIOBE.MAC M_Colora MACRO rig,col,colore,numero Ram_cur rig,col MOV CX,numero MOV AL,colore CALL CambiaAtr ENDM ; LIBRERIA UTILIZZATA DAL PROGRAMMA [opzione WinASM altrimenti non necessaria] includelib c:\arch-lab\bin\GIOBE.LIB ;PROCEDURE ESTERNE UTILIZZATE dal PROGRAMMA [NEAR, dalla LIBRERIA ~GIOBE.LIB~] ;----------------------------------------------------------------------------- EXTRN CambiaCol:NEAR EXTRN SET_cur:NEAR EXTRN VIA_cur:NEAR EXTRN RIP_cur:NEAR EXTRN KEYwait:NEAR EXTRN BIOchr1:NEAR EXTRN BIObeep:NEAR EXTRN BIOSmsg:NEAR EXTRN Delay:NEAR EXTRN Byt2Dec:NEAR EXTRN Byt2Asc:NEAR EXTRN RAMcls:NEAR EXTRN RAMpiu:NEAR EXTRN RAMcur:NEAR EXTRN RAMcorn:NEAR ; DICHIARAZIONI (VARIABILI) PER I PROGRAMMI ESTERNI: PUBLIC ATTRIB ;Attributo di colore ; DICHIARAZIONI (PROCEDURE) PER I PROGRAMMI ESTERNI: PUBLIC EditLCD2 ;/---------------------------------------------------------------------------\ ;|DEFINIZIONE DEL SEGMENTO DEL CODICE | ;\---------------------------------------------------------------------------/ ;DEFINIZIONE DEL SEGMENTO DEL CODICE ;----------------------------------------------------------------------------- ;AREA DESTINATA AI DATI DEL PROGRAMMA ;----------------------------------------------------------------------------- _prog SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:_prog,DS:_prog ORG 0100H INIZIO: JMP EditLCD2 ;/---------------------------------------------------------------------------\ ;|AREA DESTINATA AI DATI DEL PROGRAMMA | ;\---------------------------------------------------------------------------/ ATTRIB DB 0FH Address DB 00H ;Valore corrente dell'indirizzo DDRam Riga_xy DB 00H ; Coordinate della Locazione DDRam corrente nel Coln_xy DB 00H ; messaggio a Video del Visualizzatore OldChr DB ' ' ; locazioni di deposito dei caratteri del campo OldCur DB ' ' ; di acquisizione che saranno coperti dal cursore ; o dal puntatore grafico che lo rapppresenta ;Numero di caratteri per riga del Display LCD Limite DB 16 ; 2x16  00ö15  00Hö0FH riga0/40Hö4FH riga1 ; 2x20  00ö19  00Hö13H riga0/40Hö53H riga1 ; 2x24  00ö23  00Hö17H riga0/40Hö57H riga1 ; 2x32  00ö31  00Hö1FH riga0/40Hö5FH riga1 ; 2x40  00ö39  00Hö27H riga0/40Hö67H riga1 ;----------------------------------------------- ; 1x 8  00ö07  00Hö07H riga0 ; 1x16  00ö15  00Hö0FH riga0 ; 1x20  00ö19  00Hö13H riga0 ; 1x24  00ö23  00Hö17H riga0 ; 1x32  00ö31  00Hö1FH riga0 ; 1x40  00ö39  00Hö27H riga0 Titolo DB "Editor per Visualizzatore LCD con eco a Video",00H Intest1 DB "Il controllo del Visualizzatore Š garantito direttamente da Tastiera",00H Intest2 DB "L'azione dei Tasti produce effetto sia sul Display che nell'eco a video",00H Intest3 DB " adatta il Display a video al Nø di caratteri/riga (16,20,24,32,40)",00H Intest4 DB "Le frecce  spostano il cursore; lo forza all'inizio 2ø riga",00H Intest5 DB ", , e spostano il cursore nei quattro angoli",00H Intest6 DB " cancella indietro i testi scritti; cancella tutto il Display",00H Intest7 DB "Se stai lavorando con i Sistemi Operativi Windows 2000, Win NT o WinXP",00H Intest8 DB "devi prima installare e lanciare il Driver Configura_LPT1; scaricalo",00H Intest9 DB "a questo link: http://www.giobe2000.it/consigli/Scarica_VediLPT_XP.htm",00H Displ0 DB "Display Data Random Access Memory (DDram)",00H Displ1 DB "DDram",00H Displ2 DB "Visualizzatore predisposto per 40 chr/riga",00H Displ3 DB " ",00H Displ4 DB "Locazione DDRam",00H Displ5 DB "corrente: ",00H Termina DB "Esc per terminare",00H CopyRgh DB " - Copyright (c) 2003 - Giorgio Ober",00H ;/---------------------------------------------------------------------------\ ;| AREA DESTINATA ALLE PROCEDURE DEL PROGRAMMA | ;\---------------------------------------------------------------------------/ ;/---------------------------------------------------------------------------\ ;|PROCEDURA : DeskTop | ;|DESCRIZIONE: Procedura che inizializza completamente il piano di lavoro.| ;\---------------------------------------------------------------------------/ DeskTop:CALL RAMcls ;Pulisce lo schermo e inizializza il segmento ;dedicato alla RamVideo (ES=0B800H) RAMrepC 80,' ',0,0,1FH ; Barra del Titolo M_msgC Titolo,0,15,1FH ; RAMrepC 80,' ',20,0,1FH ; M_msgC CopyRgh,20,29,1FH; Barra dei messaggi M_msgC Termina,20, 2,1FH; M_msgC Intest1,2,4,0FH; M_msgC Intest2,3,4,0FH; M_msgC Intest3,5,4,0FH; M_msgC Intest4,6,4,0FH; M_msgC Intest5,7,4,0FH; Messaggi di presentazione M_msgC Intest6,8,4,0FH; M_msgC Intest7,22,4,03H; M_msgC Intest8,23,4,03H; M_msgC Intest9,24,4,03H; ÿ M_Colora 5, 5,0EH, 2 ; M_Colora 6,14,0EH, 4 ;  M_Colora 6,41,0EH, 5 ; M_Colora 7, 5,0EH, 4 ; M_Colora 7,13,0EH, 4 ; M_Colora 7,21,0EH, 4 ; Evidenzia alcune parole M_Colora 7,30,0EH, 3 ; M_Colora 8, 5,0EH, 4 ; M_Colora 8,46,0EH, 2 ; M_Colora 20, 2,1EH, 3 ; M_Colora 20,67,1EH,12 ; ..... M_Colora 24,20,0EH,23 ; ..... ; Funzione BIOS che verifica la possibilit… da ; parte della ROM BIOS di impostare adeguatamen- MOV AH,12H ; te le sue linee di partenza e di arrivo con MOV AL,01H ; cui Š costruito il Cursore, in accordo con MOV BL,34H ; l'altezza del carattere usato nel modo testo INT 10H ; corrente; con AL=01H l'emulazione CGA del Cur- ; sore Š disabilitata ed Š possibile gestire ; ogni linea tra quelle del carattere corrente; ; con AL=00H invece (emulazione CGA abilitata) ; non tutte le scelte possibili sono assicurate! ; Funzione BIOS che fissa la dimensione del cur- ; sore lampeggiante, prodotto dall'hardware del ; video SOLO nei modi testo tracciando una o pi— MOV CH, 0 ;Start; linee di Pixel nello spazio riservato al ca- MOV CL,15 ; End; rattere che sta per essere scritto. La linea MOV AH,01H ; di partenza (in alto) Š specificata in CH con INT 10H ; un numero a partire da 00H; quella finale (in ; basso) posta in CL, assumere il valore massimo ; 07 per la CGA, 13 per la EGA e 15 per la VGA ; Organizza la stampa del Visualizzatore a Video CALL Display ; copia esatta di quello sotto esame, LCD, nel ; punto indicato dalle due variabili "rigaIni", RET ; "colnIni", modificabile a piacere ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Display | ;|DESCRIZIONE: Organizza la stampa del Visualizzatore a Video, copia esatta | ;| di quello sotto esame, LCD; la procedura Š molto sofisticata | ;| perchŠ Š un grado di posizionare in modo dinamico ogni | ;| elemento della struttura, a partire dal valore predisposto | ;| nelle due variabili "rigaIni", "colnIni" fissate a piacere | ;| all'inizio del programma. Gli elementi della struttura posti | ;| a video nel punto giusto sono: i testi di presentazione e di | ;| commento, la cornice di acquisizione e quella dei caratteri | ;| eccedenti in DDram (funzione del valore prefissato nella | ;| variabile [Limite], i valori di taratura del campo attivo | ;| (anch'essi funzione del valore prefissato in [Limite]). | ;\---------------------------------------------------------------------------/ Display:MOV DH,rigaIni ;Assume le coordinate dinamiche del campo di MOV DL,colnIni ;acquisizione (Visualizzatore) a Video, in PUSH DX ;accordo con le costanti rigaIni e colnIni PUSH DX ;----------------------------------------------- PUSH DX ;----------------------------------------------- SUB DH,3 ; M_msgC Displ0,DH,DL,0FH; Stampa dinamica del testo di presentazione del ADD DL,36 ; Visualizzatore a Video M_msgC Displ1,DH,DL,0EH; SUB DL,37 ; INC DH ; M_msgC Displ3,DH,DL,0EH; Annulla la visualizzazione delle tarature ADD DH,5 ; precedenti M_msgC Displ3,DH,DL,0EH; SUB DH,5 ; MOV AH,CS:[Limite]; Stampa l'indirizzo DDram della prima DEC AH ; locazione della prima riga (sempre 00H) MOV AL,00H ; CALL Add_Byt ; ADD DL,AH ; Stampa l'indirizzo DDram dell'ultima ADD AL,AH ; locazione della prima riga (dinamico) CALL Add_Byt ; ADD DH,5 ; MOV AL,40H ; Stampa l'indirizzo DDram dell'ultima ADD AL,AH ; locazione della seconda riga (dinamico) CALL Add_Byt ; SUB DL,AH ; Stampa l'indirizzo DDram della prima MOV AL,40H ; locazione della seconda riga (sempre 40H) CALL Add_Byt ; INC DL ; INC DH ; M_msgC Displ2,DH,DL,0FH; ADD DL,31 ; Stampa dinamica del testo di commento del M_COLOR 0EH ; Visualizzatore a Video M_CURSOR DH,DL ; MOV AL,CS:[Limite]; CALL BYT2DEC ; MOV DH,rigaIni ; M_msgC Displ4,DH,9,0FH; INC DH ; M_msgC Displ5,DH,9,0FH; MOV DL,21 ; MOV CS:[Riga_xy],DH; Stampa dinamica del testo di commento alla MOV CS:[Coln_xy],DL; Locazione DDRam corrente M_COLOR 0EH ; MOV AL,CS:[Address]; CALL Add_Byt ; POP DX ; ---------------------------------------------- MOV AL,CS:[Limite]; Stampa dinamicamente la cornice corrispondente MOV BH,00H ; al campo di visualizzazone dell'effettivo LCD MOV BL,00H ; in uso MOV AH,4 ; BH=00=senza ombreggiatura ADD AL,2 ; BL=00=tratto semplice DEC DH ; AH,AL=altezza,larghezza DEC DL ; DH,DL=riga,colonna MOV CX,1000H ; CX=pagina in cui salvare i caratteri coperti M_COLOR 04H ; colore 04H (rosso su nero) CALL RamCorn ; POP DX ; --- Coordinate iniziali ---------------------- M_COLOR 2AH ; MOV CL,CS:[Limite]; MOV CH,00H ; MOV AL,' ' ; RAM_cur DH,DL ; Colora il campo di visualizzazione attivo PUSH CX ; con la giusta (dinamica) quantit… di caratteri CALL RAMpiu ; per riga del Display LCD in uso POP CX ; INC DH ; RAM_cur DH,DL ; CALL RAMpiu ; MOV AH,CS:[Limite]; DEC AH ; SUB DH,2 ; CALL Segna_D ; Marca con una freccia, '' o '', il punto ADD DL,AH ; dinamico corrispondente ai quattro indirizzi CALL Segna_D ; DDram iniziale e finale delle due righe LCD ADD DH,3 ; CALL Segna_S ; SUB DL,AH ; CALL Segna_S ; PUSH DX ; MOV DH,rigaIni ; MOV DL,colnIni ; ADD DL,41 ; DEC DH ; Annulla la parte finale del visualizzatore M_Colora DH,DL,00H,3 ; dei caratteri non previsti dal Display LCD INC DH ; in uso M_Colora DH,DL,00H,3 ; INC DH ; M_Colora DH,DL,00H,3 ; INC DH ; M_Colora DH,DL,00H,3 ; POP DX ; ADD DL,AH ; MOV AH,CS:[Limite]; Numero di caratteri per riga del Display LCD CMP AH,40 ; JE Displ__ ; MOV AL,40 ; SUB AL,AH ; Nø caratteri da aggiungere per 40/chr per riga PUSH AX ; --------------------------------------------- MOV BH,00H ; Stampa dinamicamente la cornice corrispondente MOV BL,00H ; al campo dei caratteri non visualizzati dal MOV AH,4 ; effettivo LCD in uso (presenti solo in DDram) ADD AL,2 ; BH=00=senza ombreggiatura SUB DH,3 ; BL=00=tratto semplice ADD DL,2 ; AH,AL=altezza,larghezza PUSH DX ; DH,DL=riga,colonna MOV CX,1000H ; CX=pagina in cui salvare i caratteri coperti M_COLOR 04H ; colore 04H (rosso su nero) CALL RamCorn ; POP DX ; Recupera le coordinate iniziali POP CX ; MOV CH,00H ; INC DH ; INC DL ; M_COLOR 08H ; MOV AL,'°' ; RAM_cur DH,DL ; Colora il campo dei caratteri non visualizzati PUSH CX ; con la giusta (dinamica) quantit… di caratteri CALL RAMpiu ; per riga dell'effettivo LCD in uso (presenti POP CX ; solo in DDram) INC DH ; RAM_cur DH,DL ; CALL RAMpiu ; Displ__:POP DX ; Fissa la Riga e la Colonna ai valori iniziali, MOV AL,00H ; rigaIni e colnIni e prepara il valore iniziale RET ; anche per la Locazione DDRam corrente [Address] ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Delay__ | ;|DESCRIZIONE : Il ritardo prodotto Š legato dalla velocit… del processore | ;| perch‚ utilizza le un ciclo di istruzioni.. Š di circa 1 ms | ;\---------------------------------------------------------------------------/ Delay__:PUSH CX MOV CX,0000H ;65536 del2_: PUSH AX PUSH BX PUSH CX PUSH DX POP DX POP CX POP BX POP AX LOOP del2_ POP CX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Delay_ | ;|DESCRIZIONE: Impone un ritardo PORTABILE di 55 millisecondi. | ;| [questa procedura produce, purtroppo, effetti troppo lenti] | ;\---------------------------------------------------------------------------/ Delay_: PUSH CX PUSH AX MOV CX,1 CALL Delay POP AX POP CX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Out_By8 | ;|DESCRIZIONE: In ingresso AL deve essere predisposto con il byte esadeci-| ;| male da spedire al controller HD 44780, attraverso il regi-| ;| stro di dato (0378H) della porta parallela. | ;| Il valore presisposto in AH serve per predisporre il segnale| ;| RS a 0 (AH=00H) se il byte da scrivere Š un codice operativo| ;| (istruzione) o RS a 1 (AH=01H) se invece deve essere scritto| ;| un carattere (dato). | ;| La procedura ricostruisce la sequenza temporale richiesta| ;| sui segnali RS, R/W e ENABLE del controller HD 44780 del| ;| modulo visualizzatore, assicurando le condizioni ideali per| ;| l'output verso il modulo LCD, con l'aiuto del registro di| ;| controllo (037AH) della porta parallela. | ;| /----------\ I bit3 e bit0 della porta di controllo della parallela | ;| | NB | (037AH) sono invertiti internamente e vanno riportati al | ;| \----------/ loro valore naturale (di nuovo invertiti) da software !! | ;| /----------\ Questa procedura organizza la gestione dei dati verso il | ;| | NB | mudulo visualizzatore con INTERFACCIA A 8 BIT !! | ;| \----------/ | ;\---------------------------------------------------------------------------/ ; -\ /-------------------\ /---- ; SCRITTURA Carattere (RS=1) DATA / dato o istruzione / ; o -/ \-------------------/ \---- ; SCRITTURA Istruzione (RS=0) ENABLE /---\ ; ------/ \----------------- ; WRITE ; ------------------------------ Out_By8:PUSH DX MOV BL,AL ; Salva il valore del byte (dato o istruzione) ;/-[ segnali ]-*-[bit del registro 037AH]-*-byte\ ;|    |b3/neg b2/dir b1 b0/neg|  | MOV AL,00001011B ;| E RS x R/W | EN_ RS xx R/W_|  | ;| 0 0 x 0 | 1 0 1 1 | 0BH | ;\-OUT ISTRUZ--*-------VALORE in AL-------*--AL-/ CMP AH,00H ; AH=00H  RS0 da scrivere codice operativo JE Out_By0 ;/AH=01H  RS1 da scrivere carattere (dato) ;/-[ segnali ]-*-[bit del registro 037AH]-*-byte\ ;|    |b3/neg b2/dir b1 b0/neg|  | MOV AL,00001111B ;| E RS x R/W | EN_ RS xx R/W_|  | ;| 0 1 x 0 | 1 1 1 1 | 0FH | ;\-OUT CARATT--*-------VALORE in AL-------*--AL-/ Out_By0:MOV DX,037AH ; Forza i segnali Enable, RS e R/W ai livelli OUT DX,AL ; desiderati (0 , 1, 0) tramite il Registro di ; Controllo della parallela, 037AH CALL Delay__ ; Ritardo Tas (Address Setup Time, almeno 60 ns ; prima di riportare alto il segnale Enable) PUSH AX ; Salva il valore di AH (dato o istruzione) MOV AL,BL ; Prepara per tempo il byte (dato o istruzione) MOV DX,0378H ; sul bus dati del controller (via parallela) OUT DX,AL ; POP AX ; Recupera il valore di AH (dato o istruzione) ;/-[ segnali ]-*-[registro 037AH]-\Forza a "1" ;|    | b3 b2 b1 b0 |il segnale AND AL,11110111B ;| E RS x R/W | EN_ RS xx R/W_ |Enable (cioŠ ;| 1 inalterati| 0 inalterati |bit3 a "0") ;\-OUT ISTRUZ--*--VALORE in AL----/ MOV DX,037AH ; Forza i segnali Enable, RS e R/W ai livelli OUT DX,AL ; desiderati (1 , 1, 0) tramite il Registro di ; Controllo della parallela, 037AH CALL Delay__ ; Ritardo Tw (Enable Pulse Width, al minimo 450 ; ns prima di riportare basso il segnale Enable) ;/-[ segnali ]-*-[registro 037AH]-\Forza a "0" ;|    | b3 b2 b1 b0 |il segnale OR AL,00001000B ;| E RS x R/W | EN_ RS xx R/W_ |Enable (cioŠ ;| 0 inalterati| 1 inalterati |bit3 a "1") ;\-OUT ISTRUZ--*--VALORE in AL----/ ; Forza i segnali Enable, RS e R/W ai livelli ; desiderati (0 , 1, 0) tramite il Registro di ; Controllo della parallela, 037AH; il byte OUT DX,AL ; presente sul bus dati viene scritto sul fronte ; di discesa di E [si da per scontato che esso ; sia presente sul bus almeno 195 ns (Tds, Data ; Setup Time) prima che E torni a '0' ; Ritardo Th/Tah: il dato deve essere mantenuto ; sul bus almeno altri 10 ns (Th, Data Hold Time) ; dopo che il segnale Enable Š tornato basso. CALL Delay__ ; Non appena il segnale di abilitazione Enable ; viene riportato a '0' devono passare almeno 20 ; ns (Tah, Address Hold Time) prima di rilasciare ; i segnali RS e R/W; MOV AL,BL ; Lascia in uscita (in AL) il valore del byte ; (dato o istruzione) appena messo sull'LCD POP DX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Out_By4 | ;|DESCRIZIONE: In ingresso AL deve essere predisposto con il byte esadeci-| ;| male da spedire al controller HD 44780, attraverso il regi-| ;| stro di dato (0378H) della porta parallela. | ;| RS a 0 (AH=00H) se il byte da scrivere Š un codice operativo| ;| (istruzione) o RS a 1 (AH=01H) se invece deve essere scritto| ;| un carattere (dato). | ;| La procedura ricostruisce la sequenza temporale richiesta| ;| sui segnali RS, R/W e ENABLE del controller HD 44780 del| ;| modulo visualizzatore, assicurando le condizioni ideali per| ;| l'output verso il modulo LCD, con l'aiuto del registro di| ;| controllo (037AH) della porta parallela. | ;| /----------\ I bit3 e bit0 della porta di controllo della parallela | ;| | NB | (037AH) sono invertiti internamente e vanno riportati al | ;| \----------/ loro valore naturale (di nuovo invertiti) da software !! | ;| /----------\ Questa procedura organizza la gestione dei dati verso il | ;| | NB | mudulo visualizzatore con INTERFACCIA A 4 BIT !! (di fatto | ;| \----------/ il byte da scrivere viene proposto sul bau in due tempi). | ;\---------------------------------------------------------------------------/ Out_By4:PUSH DX PUSH AX ;Salva il valore del byte di dato o di comando CALL Out_By8 ;Scrive il nibble alto (D7-D4) del dato o istruz. SHL AL,1 ; Sposta i quattro bit meno significativi del SHL AL,1 ; byte da scrivere al posto di quelli pi— SHL AL,1 ; significativi di AL SHL AL,1 ; CALL Out_By8 ;Scrive il nibble basso (D3-D0) del dato o istruz. POP AX ;Recupera il valore del byte di dato o di comando POP DX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Pre_Ini | ;|DESCRIZIONE: Inizializza il controller HD 44780, simulando l'attivazione | ;| della linea di RESET; vengono erogati tre bytes a 30H | ;| separati da piccoli ritardi pesati; per default viene | ;| predisposta l'interfaccia a 8 bit, senza curarsi, per ora, | ;| della forma del visualizzatore e della matrice del carattere| ;\---------------------------------------------------------------------------/ Pre_Ini:MOV CX,15 ; Pre_0: CALL Delay__ ; Ritardo iniziale di 15 ms (con Vcc=5V) LOOP Pre_0 ; ; Predispone le successive chiamate di Out_By8 MOV AH,00H ; per provvedere alla scrittura di un comando ; cioŠ a portare il segnale RS=0, istruzione. ; Predispone l'interfaccia a 8 bit senza curarsi ; della forma del visualizzatore e della matrice MOV AL,30H ; del carattere; il codice operativo pu• essere CALL Out_By8 ; dunque ambiguo su tutti i quattro bit meno si- ; gnificativi, cioŠ sar… del tipo 0011 xxxx ; 30H=0011 00xxB interfaccia a 8 bit MOV CX,5 ; Pre_1: CALL Delay__ ; Ulteriore ritardo di 4,1 ms LOOP Pre_1 ; ; Ripete la predisposizione dell'interfaccia a 8 MOV AL,30H ; bit, ancora in modo ambiguo su tutti i quattro CALL Out_By8 ; bit meno significativi: va bene ancora il ; codice operativo 30H=0011 00xxB ; Ritardo finale di 0,1 ms, incluso nell'esecu- ; zione della procedura appena eseguita MOV AL,30H ; Ripete per la terza volta la predisposizione CALL Out_By8 ; "ambigua" dell'interfaccia a 8 bit; il codice ; operativo sar… ancora 30H=0011 00xxB RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Mia_Ini | ;|DESCRIZIONE: Predispone il controller HD 44780 per gestire il visualizza-| ;| tore nel modo operativo desiderato, comunque con interfaccia| ;| a 4 bit: | ;| Cancella Display 00000001 01H Azzera la memoria DDRam (Clear Display) | ;| Accesso Caratteri 000001IS 06H # I=1 (bit1) > autoincrem.indirizzo DDRam| ;| # S=0 (bit0) > display bloccato | ;| Modo del Display 00001DCB 0FH # D=1 (bit2) > display acceso | ;| # C=1 (bit1) > cursore visibile | ;| # B=1 (bit0) > a forma lampeggiante | ;| Scorrimento Displ 0001SRxx 14H # S/C=0(bit3) > si muove il cursore | ;| # R/L=1(bit2) > verso destra | ;| Parametri 001DNFxx 28H # DL=0(bit4) > interfaccia a 4 bit | ;| # N=1 (bit3) > visualizzatore a 2 linee | ;| # F=0 (bit2) > matrice carattere 5x7 pix | ;\---------------------------------------------------------------------------/ Mia_Ini: ; Predispone le successive chiamate di Out_By8 MOV AH,00H ; per provvedere alla scrittura di un comando ; cioŠ a portare il segnale RS=0, istruzione. ; Predispone l'interfaccia a 4 bit senza curarsi ; della forma del visualizzatore e della matrice MOV AL,20H ; del carattere; il codice operativo pu• essere CALL Out_By8 ; dunque ambiguo su tutti i quattro bit meno si- ; gnificativi, cioŠ sar… del tipo 0010 xxxx ; 20H=0010 00xxB interfaccia a 4 bit ; Fissa i dettagli dell'interfaccia a 4 bit (DL= ; bit4=0) cominciando da ora ad usare la met… MOV AL,28H ; alta del bus dati (cioŠ dando per scontato che CALL Out_By4 ; i bit da BD3 a DB0 non sono pi— disponibili); ; si impone: visualizzatore a 2 linee (N=bit3=1) ; e matrice carattere con 5x7 pixel (F=bit2= 0); ; il codice operativo Š dunque 0010 10xx (=28H) MOV AL,01H ; Azzera la memoria DDRam (Clear Display ): il CALL Out_By4 ; codice operativo necessario Š 0000 0001 (=01H) ; Fissa il modo di gestire il display: con auto- MOV AL,06H ; incremento dell'indirizzo DDRam e del cursore CALL Out_By4 ; (I=bit1=1) e con display bloccato (S=bit0=0); ; il codice operativo Š dunque 0000 0110 (=06H) ; Inizializza le caratteristiche del display per MOV AL,0FH ; display acceso (D=bit2=1), cursore visibile CALL Out_By4 ; (C=bit1=1) e a forma lampeggiante (B=bit0=1); ; il codice operativo Š dunque 0000 1111 (=0FH) ; Inizializza lo scorrimento sul display: fissa MOV AL,14H ; il movimento del cursore (S/C=bit3=0) e verso CALL Out_By4 ; destra (R/L=bit2=1); il codice operativo Š ; dunque 0001 01xx (=14H) MOV AL,00H ; Fissa il cursore nella prima posizione, in MOV CS:[Address],AL; alto a sinistra, e istruisce il controller LCD OR AL,80H ; puntando anche la prima locazione della sua CALL Out_By4 ; memoria DDRam, di indirizzo xxxxxxx=0000000; ; l'istruzione Š del tipo 1xxxxxxx=10000000=80H MOV AL,00H RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : FissaAdd | ;|DESCRIZIONE: Indirizza la locazione della DDRam (memoria Dati del Display) | ;| che corrispondente alla posizione di stampa corrente, quella | ;| nella quale sar… visibile il cursore, sia sul Visualizzatore | ;| LCD che in quello simulato a video; aggiorna anche il valore | ;| contenuto nella variabile locale che memorizza la posizione. | ;\---------------------------------------------------------------------------/ FissaAdd: ; Predispone la successiva chiamata di Out_By8 MOV AH,00H ; per provvedere alla scrittura di un comando ; cioŠ a portare il segnale RS=0, istruzione. ; Annota la posizione corrente del cursore nella MOV CS:[Address],AL; memoria DDRam e ricostruisce l'istruzione per OR AL,80H ; per il controller LCD, forzando (con la OR) il CALL Out_By4 ; bit7 a 1, come prevede l'istruzione a ci• ; delegata; l'istruzione sar… del tipo 1xxxxxxx ; da 80H (0,0) a A7H (0,39) sulla prima linea RET ; da C0H (1,0) a E7H (1,39) sulla seconda linea ;/---------------------------------------------------------------------------\ ;|PROCEDURA : FissaCur | ;|DESCRIZIONE: Mette a Video il Cursore "°", nella posizione indicata da DH e| ;| DL (riga e colonna) provvedendo prima a salvare il carattere| ;| che sar… coperto dalla sua forma, e indicando in posizione| ;| relativamente costante il valore dell'indirizzo corrente in| ;| DDRam (memoria Dati del Display) | ;\---------------------------------------------------------------------------/ FissaCur:PUSH DX ; MOV DH,CS:[Riga_xy]; MOV DL,CS:[Coln_xy]; Stampa dinamica del testo di commento alla M_COLOR 0EH ; Locazione DDRam corrente MOV AL,CS:[Address]; CALL Add_Byt ; POP DX ; PUSH AX CALL RAMcur ; Assume il carattere che sar… coperto MOV AL,ES:[DI] ; direttamente dalla RamVideo, e ne fa copia MOV CS:[OldChr],AL; nella variabile locale [OldChr] ; Mostra un puntatore sulla cornice del campo di CALL Segna_Cur ; acquisizione in "bianco lampeggiante su rosso" ; per evidenziare il movimento del cursore sul ; Visualizzatore a Video. M_CURSOR DH,DL ; Mostra il cursore sul Display a Video ; M_Chr '°',DH,DL,2AH ; <<<<< alternativa per cursore fisso e coprente POP AX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Segna_Cur | ;|DESCRIZIONE: Mostra sulla cornice del campo di acquisizione, in "bianco| ;| lampeggiante su rosso", un puntatore grafico lampeggiante| ;| imposto dal movimento del cursore sul Visualizzatore a Video.| ;\---------------------------------------------------------------------------/ Segna_Cur:PUSH AX PUSH CX PUSH DX MOV AL,'' ; MOV DH,rigaIni ; MOV AH,CS:[Address]; Prepara la posizione di stampa e il carattere CMP AH,40H ; da utilizzare, in funzione della riga corrente JB Segna_1 ; MOV AL,'' ; ADD DH,3 ; Segna_1:DEC DH ; PUSH AX ; PUSH DX ; CALL RAMcur ; Salva il carattere del campo di acquisizione MOV AL,ES:[DI] ; che sar… coperto dal puntatore lampeggiante MOV CS:[OldCur],AL; direttamente dalla RamVideo nella [OldCur] POP DX ; POP AX ; M_CURSOR DH,DL ; M_COLOR 4FH ; Stampa il cursore lampeggiante al posto giusto CALL BIOchr1 ; POP DX POP CX POP AX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Segna_U / Segna_D | ;|DESCRIZIONE: Marca con una freccia il punto dinamico corrispondente ai | ;| quattro indirizzi DDram iniziale e finale delle due righe LCD | ;\---------------------------------------------------------------------------/ Segna_S:PUSH AX MOV AL,'' Segna__:M_CURSOR DH,DL M_COLOR 04H CALL Biochr1 M_COLOR 0EH POP AX RET Segna_D:PUSH AX MOV AL,'' JMP SHORT Segna__ ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Old_Chr | ;|DESCRIZIONE: Ripropone il carattere coperto di volta in volta dal Cursore, | ;| nei casi in cui Š necessario, come dopo la pressione di Invio| ;| o di BackSpace. | ;\---------------------------------------------------------------------------/ Old_Chr:PUSH AX MOV AL,CS:[OldChr]; Assume dalla variabile locale [OldChr] il CALL RAMcur ; carattere coperto in precedenza dal Cursore ° MOV ES:[DI],AL ; e lo rimette al suo posto, in RamVideo POP AX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Old_Col | ;|DESCRIZIONE: Recupera il colore "rosso su nero" della cornice del campo di | ;| acquisizione, per annullare l'effetto del puntatore grafico | ;| lampeggiante imposto dal movimento del cursore sul Display e | ;| sul Visualizzatore a Video | ;\---------------------------------------------------------------------------/ Old_Col:PUSH AX PUSH CX PUSH DX MOV DH,rigaIni MOV AL,CS:[Address] CMP AL,40H JB Old_Co1 ADD DH,3 Old_Co1:DEC DH CALL RAMcur ; Rimette al suo posto il carattere del campo di MOV AL,CS:[OldCur]; acquisizione coperto in precedenza dal MOV ES:[DI],AL ; puntatore lampeggiante M_Colora DH,DL,04H,1 POP DX POP CX POP AX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : Add_Byt | ;|DESCRIZIONE: Stampa a video l'indirizzo della DDRAM corrispondente agli| ;| attuali quattro angoli del Visualizzatore LCD | ;\---------------------------------------------------------------------------/ Add_Byt:PUSH AX M_CURSOR DH,DL CALL Byt2Asc MOV AL,'H' CALL BIOchr1 POP AX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : CambiaAtr | ;|DESCRIZIONE: Cambia il colore dei CX caratteri consecutivi puntati in| ;| ingresso da DH (riga),DL (colonna) con quello passato in AL. | ;\---------------------------------------------------------------------------/ CambiaAtr:INC DI Cambia_:MOV ES:[DI],AL ADD DI,2 LOOP Cambia_ RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : DDR2add | ;|DESCRIZIONE: Converte l'indirizzo corrente della DDRam del Visualizzatore | ;| LCD nelle coordinate dinamiche DH,DL (riga, colonna) | ;\---------------------------------------------------------------------------/ DDR2add:PUSH AX MOV DL,colnIni MOV DH,rigaIni MOV AH,DH ADD AH,2 CMP AL,40H JB DDR2Ad SUB AL,40H INC DH CMP DH,AH JNE DDR2Ad MOV DH,rigaIni DDR2Ad: ADD DL,AL POP AX RET ;/---------------------------------------------------------------------------\ ;/--------------------------------------------\| EditLCD2 proc NEAR ;| AREA DEDICATA AL MAIN PROGRAM || ;\--------------------------------------------/| ;\---------------------------------------------------------------------------/ MOV AL,16 ; Per default Š previsto un Visualizzatore con MOV CS:[Limite],AL; 16 caratteri per riga (e 24 nascosti, in LCD) MOV Byte Ptr CS:[Address],00H; Valore iniziale dell'indirizzo DDRam CALL DESKTOP ;Inizializza completamente il piano di lavoro ; Inizializza il controller HD 44780, simulando ; l'attivazione della linea di RESET; vengono CALL Pre_Ini ; erogati tre bytes a 30H separati da piccoli ; ritardi "pesati"; per default viene predisposta ; l'interfaccia a 8 bit ; Predispone il controller HD 44780 per gestire ; il visualizzatore nel modo operativo desiderato ; ************* Parametri >>> 001DNFxx >>> 28H ; # DL=0(bit4) > interfaccia a 4 bit ; # N=1 (bit3) > visualizzatore a 2 linee ; # F=0 (bit2) > matrice carattere 5x7 pix ; ****** Cancella Display >>> 00000001 >>> 01H ; # Azzera la memoria DDRam (Clear Display ; ***** Accesso Caratteri >>> 000001IS >>> 06H CALL Mia_Ini ; # I=1 (bit1) > autoincrem.indirizzo DDRam ; # S=0 (bit0) > display bloccato ; ****** Modo del Display >>> 00001DCB >>> 0FH ; # D=1 (bit2) > display acceso ; # C=1 (bit1) > cursore visibile ; # B=1 (bit0) > a forma lampeggiante ; *** Scorrimento Display >>> 0001SRxx >>> 14H ; # S/C=0(bit3) > si muove il cursore ; # R/L=1(bit2) > verso destra ;------------------------------ ---------------------------------------------- ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della Rientra:CALL FissaAdd ; memoria DDRam del controller LCD, con valori: CALL FissaCur ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente Rien_0: CALL KEYwait ; Aspetta decisioni ; Recupera il colore "rosso su nero" della ; cornice del campo di acquisizione, per CALL Old_Col ; annullare l'effetto del puntatore grafico ; lampeggiante imposto dal movimento del cursore ; sul Display e sul Visualizzatore a Video | CMP AL,00H ; Si tratta di tasto Funzionale... JE KeyFunz ; Va servito a parte CMP AL,Invio ; JNE Rien_1 ; Servizio per la pressione di JMP Serv_Invio ; Rien_1: CMP AL,BackSp ; JNE Rien_2 ; Servizio per la pressione di JMP Serv_BkSp ; ; ; NB !! per il Servizio di JMP Serv_BkSp_ ; esiste una versione alternativa ; ; ---------------------------------------- Rien_2: CMP AL,ESC_ ; Servizio per la pressione di JE _OUT ; ; Servizio per la pressione di un comune tasto JMP Serv_Chr ; Ascii: il carattere corrispondente viene posto ; a video e trasmesso al visualizzatore KeyFunz:CMP AH,F1_ ; JNE KeyFun0 ; Servizio per la pressione di JMP Serv_F1 ; KeyFun0:CMP AH,F2_ ; JNE KeyFun1 ; Servizio per la pressione di JMP Serv_F2 ; KeyFun1:CMP AH,Frec_Su ; JNE KeyFun2 ; Servizio Scorrimento cursore: Freccia  JMP Serv_Up ; KeyFun2:CMP AH,Frec_Giu ; JNE KeyFun3 ; Servizio Scorrimento cursore: Freccia  JMP Serv_Dn ; KeyFun3:CMP AH,Frec_Dx ; JNE KeyFun4 ; Servizio Scorrimento cursore: Freccia  JMP Serv_Dx ; KeyFun4:CMP AH,Frec_Sn ; JNE KeyFun5 ; Servizio Scorrimento cursore: Freccia  JMP Serv_Sn ; KeyFun5:CMP AH,End_Fine ; JNE KeyFun6 ; Servizio Scorrimento cursore: End (=Fine) JMP Serv_End ; KeyFun6:CMP AH,Home ; JNE KeyFun7 ; Servizio Scorrimento cursore: Home JMP Serv_Hom ; KeyFun7:CMP AH,PgDn ; JNE KeyFun8 ; Servizio Scorrimento cursore: PgDn JMP Serv_PD ; KeyFun8:CMP AH,PgUp ; JNE Rien_0 ; Servizio Scorrimento cursore: PgUp JMP Serv_PU ; _OUT: MOV AH,00H ; MOV AL,01H ; Per cortesia spegne, in uscita, CALL Out_By4 ; il Visualizzatore LCD MOV AL,08H ; CALL Out_By4 ; PUSH AX ; MOV AH,12H ; MOV AL,00H ; Ripristina in uscita le dimensioni standard MOV BL,34H ; del Cursore, riabilitando l'emulazione CGA con INT 10H ; AL=00H (con la Funzione BIOS Video 12H/34H) e CALL RIP_cur ; riportando la sua dimensione a quelle standard MOV DH,23 ; CGA (inizio=CH=6, fine=CL=7, con la Funzione MOV DL,0 ; BIOS Video 01H, implementata dalla "RIP_cur") CALL SET_cur ; POP AX ; ; --------------------------------------------- ; Torna al DOS con la memoria liberata e con la ; chiusura di tutti i file; cede il controllo ; al processo padre (generalmente COMMAND.COM); MOV AH,4CH ; il valore posto eventualmente in AL prima di INT 21H ; uscire pu• essere testato in uscita con la ; funzione 4DH o mediante la lettura della ; variabile DOS "ERRORLEVEL" ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_F1 | ;|DESCRIZIONE: Commuta il controllo da 16, 20, 24, 32 o 40 caratteri per riga| ;| [****** NB: prosegue e si chiude attraverso "Serv_F2" ******]| ;\---------------------------------------------------------------------------/ TabChar DB 01 ; DB 16 ; DB 20 ; Tabella dedicata al Servizio del tasto DB 24 ; DB 32 ; DB 40 ; ;---------------------------------------------------------------------------- Serv_F1:LEA SI,TabChar MOV AL,CS:[SI] INC AL CMP AL,6 JNE Srv_F1 MOV AL,1 Srv_F1: MOV CS:[SI],AL MOV AH,00H ADD SI,AX MOV AL,CS:[SI] MOV CS:[Limite],AL ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_F2 | ;|DESCRIZIONE: Cancella i caratteri nel Display a Video e fissa il cursore e | ;| anche quelli sul Visualizzatore LCD | ;\---------------------------------------------------------------------------/ Serv_F2:CALL Display Srv_F_: PUSH AX ; Predispone la successiva chiamata di Out_By8 MOV AH,00H ; per provvedere alla scrittura di un comando ; cioŠ a portare il segnale RS=0, istruzione. MOV AL,01H ; Azzera la memoria DDRam (Clear Display ): il CALL Out_By4 ; codice operativo necessario Š 0000 0001 (=01H) POP AX ; ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_Chr | ;|DESCRIZIONE: Servizio per la pressione di un qualunque tasto Ascii; il| ;| corrispondente carattere, trovato in ingresso in AL, viene| ;| posto a video nel campo del Visualizzatore e trasmesso al| ;| controller LCD; la posizione di stampa viene aggiornata per| ;| puntare la posizione del carattere successivo, in funzione del| ;| tipo di Visualizzatore, attualmemente in uso. | ;\---------------------------------------------------------------------------/ Serv_Chr:PUSH AX ; Salva il codice Ascii del carattere da stampare ;**********************;******* Servizio di Visualizzazione su LCD **** ; Predispone la successiva chiamata di Out_By8 MOV AH,01H ; per provvedere alla scrittura di un carattere ; cioŠ a portare il segnale RS=1, carattere CALL Out_By4 ; Trasmette al controller LCD il carattere in AL ; (RS=1) e aggiorna la posizione del cursore per ; puntare il carattere successivo ; corrispondente alla posizione del primo carat- ; tere sulla seconda linea MOV AH,CS:[Limite]; Dimensione del visualizzatore LCD in uso MOV AL,CS:[Address]; Assume il valore corrente dell'indirizzo INC AL ; interno DDRam e ne incrementa il valore CMP AL,AH ; Se la posizione Š in fondo alla prima linea si JE Srv_C0 ; forza il cursore a capo della linea successiva ADD AH,40H ; CMP AL,AH ; Se la posizione Š in fondo alla seconda linea JNE Srv_C1 ; si forza il cursore a capo della prima linea MOV AL,00H ; JMP SHORT Srv_C1 ; ; Fissa l'indirizzo interno della memoria DDRam Srv_C0: MOV AL,40H ; del controller LCD per puntare l'indirizzo 40H ; Annota la posizione corrente del cursore nella ; memoria DDRam e ricostruisce l'istruzione per ; per il controller LCD, forzando (con la OR) il Srv_C1: CALL FissaAdd ; bit7 a 1, come prevede l'istruzione a ci• ; delegata; l'istruzione sar… del tipo 1xxxxxxx ; da 80H (0,0) a A7H (0,39) sulla prima linea ; da C0H (1,0) a E7H (1,39) sulla seconda linea ;**********************; ***** Servizio di Visualizzazione a Video **** POP AX ; Recupera codice Ascii del carattere da stampare M_Chr AL,DH,DL,2AH ; Stampa il carattere sul Display a Video INC DL ; Incrementa la colonna MOV AL,colnIni ; AL= colonna iniziale in entrambe le linee MOV AH,CS:[Limite]; Dimensione del visualizzatore LCD in uso ADD AH,AL ; AH= colonna successiva all'ultima possibile CMP DL,AH ; Se la posizione Š in fondo alla prima o alla JNE Srv_C3 ; seconda linea si forza il cursore a capo della ; linea opposta a quella corrente Srv_C2: MOV DL,AL ; colnIni INC DH ; Fissa il cursore a capo dell'altra linea MOV AH,rigaIni ; ADD AH,2 ; CMP DH,AH ; (rileva automaticamente se quella superiore JNZ Srv_C3 ; o se quella inferiore) MOV DH,rigaIni ; Srv_C3: CALL FissaCur ; Mostra il cursore sul Display a Video e stampa JMP Rien_0 ; il valore della Locazione DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_Invio | ;|DESCRIZIONE: La pressione del tasto "Invio" sposta la posizione di stampa | ;| per puntare il carattere all'inizio della seconda riga. | ;\---------------------------------------------------------------------------/ Serv_Invio: CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV DL,colnIni ; Prepara il puntatore Video a capo linea MOV AL,CS:[Address]; Assume il valore corrente dell'indirizzo DDRam MOV DH,rigaIni ; Prepara il puntatore Video sulla seconda linea INC DH ; MOV AH,40H ; Prepara il puntatore DDRam a inizio 2.da linea CMP AL,27H ; Se la posizione Š sulla prima linea si forza JBE Serv_I ; il cursore a capo della seconda linea ; Altrimenti (posizione sulla seconda linea) si ; forza il cursore a capo della prima linea.... MOV DH,rigaIni ; Prepara il puntatore Video sulla prima linea MOV AH,00H ; Prepara il puntatore DDRam a inizio 1.ma linea Serv_I: MOV AL,AH ; ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_Up | ;|DESCRIZIONE: La pressione della Freccia in Alto sposta la posizione di| ;| stampa sulla stessa colonna nella riga superiore; se gi… si| ;| trova in posizione superiore l'azione del tasto non ha effetto| ;\---------------------------------------------------------------------------/ Serv_Up:MOV AL,CS:[Address]; Assume il valore corrente dell'indirizzo DDRam CMP AL,40H ; Se la posizione Š sulla prima linea l'azione JGE FrUp__1 ; della pressione del tasto non ha effetto JMP Rien_0 ; ;---------------------------------------------------------------------- FrUp__1:CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV DH,rigaIni ; Prepara il puntatore Video sulla prima linea MOV DL,colnIni ; Prepara il puntatore Video a capo linea SUB AL,40H ; Se la posizione Š sulla seconda linea forza il ADD DL,AL ; cursore nella stessa colonna della linea sopra ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: FrUp__0:JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_Dn | ;|DESCRIZIONE: La pressione della Freccia in Basso sposta la posizione di| ;| stampa sulla stessa colonna nella riga inferiore; se gi… si| ;| trova in posizione inferiore l'azione del tasto non ha effetto| ;\---------------------------------------------------------------------------/ Serv_Dn:MOV AL,CS:[Address]; Assume il valore corrente dell'indirizzo DDRam CMP AL,40H ; Se la posizione Š sulla seconda linea l'azione JB FrDn__1 ; della pressione del tasto non ha effetto JMP Rien_0 ; ;---------------------------------------------------------------------- FrDn__1:CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV DH,rigaIni ; Prepara il puntatore Video sulla seconda linea INC DH ; MOV DL,colnIni ; Prepara il puntatore Video a capo linea ADD DL,AL ; Se la posizione Š sulla prima linea forza il ADD AL,40H ; cursore nella stessa colonna della linea sotto ; Indirizza la locazione della DDRam (memoria ; Dati del Display) che corrispondente alla ; posizione di stampa corrente, quella nella JMP SHORT FrUp__0 ; quale sar… visibile il cursore, sia sul ; Visualizzatore LCD che in quello simulato a ; video;aggiorna anche il valore contenuto nella ; variabile locale che memorizza la posizione. ;/---------------------------------------------------------------------------\ ;|SERVIZIO : PgUp | ;|DESCRIZIONE: La pressione di PgUp sposta la posizione di stampa nell'angolo| ;| in alto a destra, sulla riga superiore. | ;\---------------------------------------------------------------------------/ Serv_PU:CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV DH,rigaIni ; Prepara il puntatore Video sulla linea in alto MOV DL,colnIni ; Prepara il puntatore Video a capo linea MOV AH,CS:[Limite]; Dimensione del visualizzatore LCD in uso DEC AH ; Prepara il puntatore Video sul carattere in ADD DL,AH ; alto a destra, sulla prima linea; prepara MOV AL,AH ; anche il puntatore DDRam nello stesso punto ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : PgDn | ;|DESCRIZIONE: La pressione di PgDn sposta la posizione di stampa nell'angolo| ;| in basso a destra, sulla riga inferiore. | ;\---------------------------------------------------------------------------/ Serv_PD:CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV DH,rigaIni ; Prepara il puntatore Video sulla linea in basso INC DH ; MOV DL,colnIni ; Prepara il puntatore Video a capo linea MOV AH,CS:[Limite]; Dimensione del visualizzatore LCD in uso DEC AH ; Prepara il puntatore Video sul carattere in ADD DL,AH ; basso a destra, sulla seconda linea; prepara MOV AL,AH ; anche il puntatore DDRam nello stesso punto ADD AL,40H ; ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Home | ;|DESCRIZIONE: La pressione di PgUp sposta la posizione di stampa nell'angolo| ;| in alto a sinistra, sulla riga superiore. | ;\---------------------------------------------------------------------------/ Serv_Hom:CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV DH,rigaIni ; Prepara il puntatore Video sul carattere in MOV DL,colnIni ; alto a sinistra, sulla prima linea; prepara MOV AL,00H ; anche il puntatore DDRam nello stesso punto ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : End | ;|DESCRIZIONE: La pressione di PgDn sposta la posizione di stampa nell'angolo| ;| in basso a sinistra, sulla riga inferiore. | ;\---------------------------------------------------------------------------/ Serv_End:CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV DH,rigaIni ; Prepara il puntatore Video sul carattere in INC DH ; basso a sinistra, sulla seconda linea; prepara MOV DL,colnIni ; anche il puntatore DDRam nello stesso punto MOV AL,40H ; ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_Sn | ;|DESCRIZIONE: La pressione della Freccia a Sinistra sposta la posizione di| ;| stampa indietro di una posizione | ;\---------------------------------------------------------------------------/ Serv_Sn:CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV AH,CS:[Limite]; Prepara il puntatore DDRam per puntare il DEC AH ; carattere in alto a destra sulla prima linea MOV DH,rigaIni ; Prepara il puntatore Video per puntare alla MOV DL,colnIni ; posizione dell'ultimo carattere sulla prima ADD DL,AH ; linea MOV AL,CS:[Address]; Assume il valore corrente dell'indirizzo DEC AL ; interno DDRam e ne decrementa il valore CMP AL,3FH ; Se la posizione Š all'inizio della seconda JE FrSn__1 ; linea si forza il cursore in fondo alla prima MOV DL,colnIni ; CMP AL,3FH ; Arretra il puntatore Video di una posizione JB FrSn__0 ; a sinistra INC DH ; SUB DL,40H ; FrSn__0:ADD DL,AL ; CMP AL,0FFH ; Se la posizione NON Š all'inizio della prima JNE FrSn__2 ; linea si arretra normalmente di un carattere MOV DH,rigaIni ; Prepara il puntatore Video per puntare alla INC DH ; posizione dell'ultimo carattere sulla seconda MOV DL,colnIni ; linea ADD DL,AH ; ADD AH,40H ; Se la posizione Š all'inizio della prima linea ; si forza il cursore in fondo alla seconda FrSn__1:MOV AL,AH ; ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: FrSn__2:JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_Dx | ;|DESCRIZIONE: La pressione della Freccia a Destra sposta la posizione di| ;| stampa in avanti di una posizione | ;\---------------------------------------------------------------------------/ Serv_Dx:CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV AL,CS:[Address]; Assume il valore corrente dell'indirizzo INC AL ; interno DDRam e ne incrementa il valore MOV AH,CS:[Limite]; Prepara il puntatore DDRam per puntare il ADD AH,40H ; carattere in basso a destra sulla seconda ; linea MOV DH,rigaIni ; Prepara il puntatore Video per puntare alla MOV DL,colnIni ; posizione del primo carattere sulla prima ; linea CMP AL,AH ; Se la posizione Š alla fine della seconda JE FrDx__1 ; linea si forza il cursore in cima alla prima SUB AH,40H ; MOV DL,colnIni ; CMP AL,AH ; Avanza il puntatore Video di una posizione JB FrDx__0 ; a destra INC DH ; SUB DL,40H ; FrDx__0:ADD DL,AL ; CMP AL,AH ; Se la posizione NON Š alla fine della prima JNE FrDx__2 ; linea si avanza normalmente di un carattere MOV DH,rigaIni ; Prepara il puntatore Video per puntare alla MOV DL,colnIni ; posizione del primo carattere sulla seconda INC DH ; linea MOV AL,40H ; Se la posizione Š all'inizio della seconda JMP SHORT FrDx__2 ; linea ; Prepara il puntatore interno della memoria FrDx__1:MOV AL,00H ; DDRam del controller LCD all'indirizzo 00H ; per puntare alla posizione del primo carattere ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: FrDx__2:JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_BkSp | ;|DESCRIZIONE: La pressione del tasto "BackSpace" sposta la posizione di| ;| stampa indietro di una posizione, cancellando il carattere| ;| verso sinistra, anche nella memoria DDRam del controller LCD,| ;| autonomamente su ciascuna linea, bloccandosi sul primo | ;| carattere della rispettiva linea. | ;\---------------------------------------------------------------------------/ Serv_BkSp: CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV AL,CS:[Address]; Assume il valore corrente dell'indirizzo ; interno DDRam e ne decrementa il valore PUSH CX MOV CL,CS:[Limite]; Dimensione del visualizzatore LCD in uso MOV CH,AL ; CMP AL,40H ; Prepara in CX il numero di locazioni da JB Back__1 ; spostare verso sinistra, pari ai caratteri che SUB CH,40H ; sono attalmente a destra del cursore (vale per Back__1:SUB CL,CH ; entrambe le linee, autonomamente fino al loro MOV CH,00H ; termine destro PUSH AX ; PUSH DX ; Back__2:PUSH AX ; CALL DDR2add ; Preleva il carattere attualmente puntato dal CALL RAMcur ; cursore, nella posizione di stampa corrente MOV AH,ES:[DI] ; DEC AL ; CMP AL,3FH ; Punta la locazione precedente e verifica se JE Back__4 ; il servizio Š da ritenersi terminato (siamo a CMP AL,0FFH ; capolinea, o sotto (=3FH) o sopra (=FFH) JE Back__4 ; CALL DDR2add ; Sposta il carattere appena prelevato nella CALL RAMcur ; posizione precedente a quella d'ingresso, nel MOV ES:[DI],AH ; Visualizzatore a Video PUSH AX ; CALL FissaAdd ; POP AX ; Sposta il carattere appena prelevato nella MOV AL,AH ; posizione precedente a quella d'ingresso, MOV AH,01H ; anche nella memoria DDRam del Display LCD CALL Out_By4 ; POP AX ; INC AL ; Prosegue il servizio di BackSpace per tutti LOOP Back__2 ; i caratteri presenti sulla riga corrente DEC AL ; CALL DDR2add ; Sposta il carattere appena prelevato nella CALL RAMcur ; posizione precedente a quella d'ingresso, nel MOV AH,' ' ; Visualizzatore a Video MOV ES:[DI],AH ; PUSH AX ; CALL FissaAdd ; POP AX ; Sposta il carattere appena prelevato nella MOV AL,AH ; posizione precedente a quella d'ingresso, MOV AH,01H ; anche nella memoria DDRam del Display LCD CALL Out_By4 ; POP DX ; POP AX ; POP CX ; ; Fissa la variabile [Address] con il valore DEC AL ; della posizione corrente del cursore e copia DEC DL ; l'informazione nel registro puntatore della Back__3:JMP Rientra ; memoria DDRam del controller LCD, con valori: ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente Back__4:POP AX ; POP DX ; Se il servizio Š da ritenersi terminato (siamo POP AX ; sul primo carattere di una delle due linee) POP CX ; bisogna recuperare le posizioni pendenti nello JMP SHORT Back__3 ; stack e fare ritorno immediato, in attesa ;/---------------------------------------------------------------------------\ ;|SERVIZIO : Serv_BkSp_ ********* VERSIONE ALTERNATIVA **************** | ;|DESCRIZIONE: La pressione del tasto "BackSpace" sposta la posizione di| ;| stampa indietro di una posizione, cancellando il carattere| ;| verso sinistra, anche nella memoria DDRam del controller LCD;| ;| questa versione "cancella indietro" tutto il campo visivo,| ;| proseguendo sull'altra linea, non appena arriva al primo| ;| carattere della linea su cui Š entrato, e non fa arretrare i| ;| caratteri a destra di quello sotto servizio | ;\---------------------------------------------------------------------------/ Serv_BkSp_: CALL Old_Chr ; Annulla la visualizzazione del cursore nel ; punto previsito per la stampa corrente MOV AH,CS:[Limite]; Prepara il puntatore DDRam per puntare il DEC AH ; carattere in alto a destra sulla prima linea MOV DH,rigaIni ; Prepara il puntatore Video per puntare alla MOV DL,colnIni ; posizione dell'ultimo carattere sulla prima ADD DL,AH ; linea MOV AL,CS:[Address]; Assume il valore corrente dell'indirizzo DEC AL ; interno DDRam e ne decrementa il valore CMP AL,3FH ; Se la posizione Š all'inizio della seconda JE Back_2_ ; linea si forza il cursore in fondo alla prima MOV DL,colnIni ; CMP AL,3FH ; Arretra il puntatore Video di una posizione JB Back_1_ ; a sinistra INC DH ; SUB DL,40H ; Back_1_:ADD DL,AL ; CMP AL,0FFH ; Se la posizione NON Š all'inizio della prima JNE Back_3_ ; linea si arretra normalmente di un carattere MOV DH,rigaIni ; Prepara il puntatore Video per puntare alla INC DH ; posizione dell'ultimo carattere sulla seconda MOV DL,colnIni ; linea ADD DL,AH ; ADD AH,40H ; Se la posizione Š all'inizio della prima linea ; si forza il cursore in fondo alla seconda Back_2_:MOV AL,AH ; Back_3_:PUSH AX ; CALL FissaAdd ; Cancella il carattere attualmente presente sui MOV AL,' ' ; due Visualizzatori (quello a Video e l'LCD), CALL RAMcur ; Il primo direttamente a Livello RamVideo e il MOV ES:[DI],AL ; secondo predisponendo la chiamata successiva MOV AH,01H ; di Out_By4 per provvedere alla scrittura di un CALL Out_By4 ; carattere (cioŠ per a portare il segnale RS=1) POP AX ; al fine di trasmettere lo spazio al controller ; Fissa la variabile [Address] con il valore ; della posizione corrente del cursore e copia ; l'informazione nel registro puntatore della ; memoria DDRam del controller LCD, con valori: JMP Rientra ; þda 00H (0,0) a 27H (0,39) sulla prima linea ; þda 40H (1,0) a 67H (1,39) sulla seconda linea ; Inoltre mostra il cursore sul Display a Video ; e stampa il valore della Locaz. DDRam corrente EditLCD2 ENDP ; Chiusura della Procedura "Main Program" _prog ENDS ; Chiusura del Segmento di CODICE END INIZIO ; Indirizzo dell'ultima istruzione da compilare