PAGE 66,132 TITLE** PROGRAMMA di GESTIONE di programmi ASSEMBLER tipo COM (dicembre 2004) SUBTTL ** TUTORIAL ASSEMBLY -- www.giobe2000.it -- by ing. Giorgio OBER ;/---------------------------------------------------------------------------\ ;| NOME : TxD2Com2.ASM /------------------[TxD]---------------------\| ;| AUTORE : Giorgio OBER | ************* Versione 02 ************* || ;| VERSIONE : dicembre 2004 \------------------[COM2]--------------------/| ;| DESCRIZIONE : Organizza la TRASMISSIONE di DATI dalla porta seriale (UART)| ;| del computer con la tecnica dell'interruzione (INTERRUPT). | ;|/-----------\ | ;|| | Questa versione provvede SOLO al servizio delle interruzioni| ;|| | generate dal "Registro di Trasmissione Vuoto"; ciascuno dei| ;|| NB: | possibili eventi seriali potr… essere autorizzato ad inter-| ;|| | rompere fissando a 1 i bit ad essi relativi nel "Registro di| ;|| | Abilitazione Interruzioni", sulla riga di programma con| ;|| | l'etichetta "Cambia", nella Procedura "SetInt0B" (vedi sotto)| ;|\-----------/ | ;|/-----------\/------------------------------------------------------------\| ;|| ||La Trasmissione con tecnica di INTERRUZIONE Š piuttosto|| ;|| ||impegnativa e sostanzialmente non necessaria (quella che|| ;|| ||interroga (POLLING) il Registro di Stato Linea per stabilire|| ;|| ||il momento giusto per Trasmettere Š semplice e altrettanto|| ;|| ||affidabile); il Servizio alla richiesta di INT generata per|| ;|| ||"Trasmettitore Vuoto" deve controllare se il dato da mettere|| ;|| NB: ||nel Registro di Trasmissione pu• essere estratto dal Buffer|| ;|| ||di Trasmissione (se non Š vuoto) oppure se delegare questo|| ;|| ||compito direttamente alla procedura "TxD_Int"; per la stessa|| ;|| ||ragione la procedura "TxD_Int" deve controllare se il Buffer|| ;|| ||Š vuoto per decidere se spedire il dato in partenza diretta-|| ;|| ||mente al Registro di Trasmissione o se parcheggiarlo nello|| ;|| ||stesso Buffer || ;|\-----------/\------------------------------------------------------------/| ;| a) versione con presentazione (DESKTOP) | ;| b) in AUTOMATICO il programma TRASMETTE in continuazione | ;| (sulla porta COM2) la sequenza dei caratteri ascii dal | ;| primo standard [=00H, 0] all'ultimo esteso [=FFH, 255]; | ;| in MANUALE il programma aspetta la digitazione di un | ;| tasto e poi ne TRASMETTE il codice ascii, fino alla | ;| pressione del tasto | ;| c) il processo Š gestito da tastiera con diversi livelli di | ;| menu interattivi. | ;| e) il protocollo HW impostato per la TRASMISSIONE SERIALE Š:| ;| /--------------------------------\ | ;| | COM2, 9600, N, 2, 8 | | ;| \--------------------------------/ | ;|/-----------\ Per cambiare PORTA utilizzata, Velocit… di ricetrasmissione| ;|| | e Protocollo Seriale scegli altri valori tra quelli possibili| ;|| | per le costanti qui sotto; per COM_num e Baude basta spostare| ;|| NB: | il "punto e virgola" mentre per Protoc bisogna riassemblare| ;|| | il byte con i campi desiderati. | ;|| | -------------------------------------------------------------| ;|\-----------/ E' comunque disponibile la versione "TxD2Com1.ASM" per COM1. | ;| -------------------------------------------------------------| ;| Maggiori dettagli sono disponibili nella sezione dedicata | ;| alla porta seriale sul sito *** http://www.giobe2000.it *** | ;\---------------------------------------------------------------------------/ ESC_ EQU 27 ;codice del tasto _8259ct EQU 20H ;Controller interruzioni 8259, registro di comando _8259mk EQU 21H ;Controller interruzioni 8259, registro di maschera ; --------------------------------------------------------------------------- COM_num EQU 02H ;PORTA utilizzata = COM2 /--------------------------------\ ;EQU 01H ;PORTA utilizzata = COM1 |Scegli la porta COM desiderata | ;EQU 03H ;PORTA utilizzata = COM3 |[ default: programma per COM2 ] | ;EQU 04H ;PORTA utilizzata = COM4 \--------------------------------/ ;---------------------------------------------------------- ;/--------------------------------------------------------\ ;| Scegli la COSTANTE per la VELOCITA` desiderata | ;*--------*-------------------------------*---------------* ;|Costante|********** Baud RATE *********| Errore | ;*--------*-----------------------*-------*---------------* ;EQU 0900H ;|=2304 = (115200/2304) = 50.0 | 50 | ---- | ;EQU 0600H ;|=1536 = (115200/1536) = 75.0 | 75 | ---- | ;EQU 0417H ;|=1047 = (115200/1047) = 110.0 | 110 |(errore 0.026 )| ;EQU 0359H ;|= 857 = (115200/857 ) = 134.4 | 135 |(errore 0.058 )| ;EQU 0300H ;|= 768 = (115200/768 ) = 150.0 | 150 | ---- | ;EQU 0180H ;|= 384 = (115200/384 ) = 300.0 | 300 | ---- | ;EQU 00C0H ;|= 192 = (115200/192 ) = 600.0 | 600 | ---- | ;EQU 0060H ;|= 96 = (115200/96 ) = 1200.0 | 1200 | ---- | ;EQU 0040H ;|= 64 = (115200/64 ) = 1800.0 | 1800 | ---- | ;EQU 003AH ;|= 58 = (115200/58 ) = 1986.2 | 2000 |(errore 0.69) | ;EQU 0030H ;|= 48 = (115200/48 ) = 2400.0 | 2400 | ---- | ;EQU 0020H ;|= 32 = (115200/32 ) = 3600.0 | 3600 | ---- | ;EQU 0018H ;|= 24 = (115200/24 ) = 4800.0 | 4800 | ---- | ;EQU 0010H ;|= 16 = (115200/16 ) = 7200.0 | 7200 | ---- | Baude EQU 000CH ;|= 12 = (115200/12 ) = 9600.0 | 9600 | ---- | ;EQU 0006H ;|= 6 = (115200/6 ) = 19200.0 | 19200 | ---- | ;EQU 0003H ;|= 3 = (115200/3 ) = 38400.0 | 38400 | ---- | ;EQU 0002H ;|= 2 = (115200/2 ) = 57600.0 | 56000 |(errore 2.86) | ;EQU 0001H ;|= 1 = (115200/1 ) =115200.0 |115200 | ---- | ;\--------------------------------*-------*---------------/ ;---------------------------------------------------------- ;/--------------------------------------------------------\ ;| Scegli la COSTANTE associata al PROTOCOLLO SERIALE | ;*---------[7654 3210]=07H--------------------------------* ;| default .... ..11 >>>>> 8 bit per il DATO | Protoc EQU 07H ;| .... ..10 >>>>> 7 bit per il DATO | ;| .... ..01 >>>>> 6 bit per il DATO | ;| .... ..00 >>>>> 5 bit per il DATO | ;*--------------------------------------------------------* ;| default .... .1.. >>>>> 2 bit di stop | ;| .... .0.. >>>>> 1 bit di stop | ;*--------------------------------------------------------* ;| ...0 1... >>>>> parit… dispari | ;| ...1 1... >>>>> parit… pari | ;| default ...x 0... >>>>> nessuna parit… | ;*--------------------------------------------------------* ;| ..0. .... >>>>> parit… disabilitata | ;| .0.. .... >>>>> Break disabilitato | ;| 0... .... >>>>> programmaz. del protocollo | ;\--------------------------------------------------------/ ; MACRO UTILIZZATE DAL PROGRAMMA: include c:\arch-lab\bin\GIOBE.MAC ;/[nuova MACRO locale]------------------------------------------------\ ;|M_Corn Organizza la stampa di una cornice a video, predisponendo i | ;| parametri nei corretti registri, per la procedura RamCorn | ;\--------------------------------------------------------------------/ M_corn MACRO altezza,larghezza,riga,colonna,colore,tipo,ombra,salva MOV AH,altezza ;\[ altezza compresa cornice ] MOV AL,larghezza ;|[ larghezza compresa cornice ] MOV DH,riga ;|[ riga angolo in alto a sinistra ] MOV DL,colonna ;|[ colonna angolo in alto a sinistra ] MOV BL,tipo ;|[ tipo 0=tratto semplice; 1=tratto doppio] MOV BH,ombra ;|[ ombra 0=senza; 1=con ombreggiatura ] MOV CX,salva ;|[ salva RAM in cui salvare l'area coperta ] M_COLOR Colore ;|[ colore: colore della cornice e sfondo ] CALL RamCorn ;/ 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 BIOchr1:NEAR EXTRN RIEMPI:NEAR EXTRN BIOSmsg:NEAR EXTRN SET_cur:NEAR EXTRN VIA_cur:NEAR EXTRN RIP_cur:NEAR EXTRN KEYwait:NEAR EXTRN Byt2Asc:NEAR EXTRN Wor2Dec:NEAR EXTRN RamCorn:NEAR ; DICHIARAZIONI (VARIABILI) PER I PROGRAMMI ESTERNI: PUBLIC ATTRIB ;Attributo di colore ; DICHIARAZIONI (PROCEDURE) PER I PROGRAMMI ESTERNI: PUBLIC TxD2Com2 ;DEFINIZIONE DEL SEGMENTO DEL CODICE ;----------------------------------------------------------------------------- _prog SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:_prog,DS:_prog ORG 0100H INIZIO: JMP TxD2Com2 ;AREA DESTINATA AI DATI DEL PROGRAMMA ;----------------------------------------------------------------------------- ATTRIB DB 00H Numero DW 0001H Titolo DB "Programmi per il Collaudo della Porta Seriale ",00H Titolo1 DB "COM",00H Tema0 DB "TxD2Com2-TRASMISSIONE SERIALE su COM2" DB " - Protocollo HW: 9600,N,2,8",00H Tema1 DB "NB: Trasmissione gestita in " DB "INTERRUPT con Buffer di Trasmissione",00H Nocom0 DB "La PORTA SERIALE desiderata, COM , ",00H Nocom1 DB "non Š",00H Nocom2 DB " disponibile",00H Centro1 DB "Caratteri Ascii trasmessi",00H Centro2 DB "Bytes trasmessi",00H MENU01 DB "Inizia",00H MENU02 DB "Quit",00H MENU03 DB "Interrompi ",00H MENU04 DB "Riprendi ",00H MENU05 DB "Cancella",00H MENU06 DB "Trasmissione Manuale o Automatica?",00H MENU07 DB "Digita il carattere da trasmettere",00H MENU08 DB "ESC ",00H BytTxD DB "Bytes trasmessi: ",00H DatTxD DB 00H DepoMod DB 00H ;[DepoMod]=00 con "A" Trasmissione Automatica ;[DepoMod]=01 con "M" Trasmissione Manuale RigAsci DB 2 ;Numero della riga corrente per i caratteri ColAsci DB 1 ;Numero della colonna corrente per i caratteri AtrAsci DB 0EH ;Colore corrente usato nella stampa dei caratteri RigByte DB 8 ;Numero della riga corrente per i bytes ColByte DB 1 ;Numero della colonna corrente per i bytes AtrByte DB 1FH ;Colore corrente usato nella stampa dei bytes Dep8259 DB 00H ;Questa variabile tiene copia del contenuto originale del ;Registro di Abilitazione delle Interruzioni [port_9] per ;poterlo ripristinare prima di rimuovere la procedura di ;servizio dell'interruzione IRQ3 Old_Int0B DW 0000H ;Deposito per il Vettore INT 0BH originale attivato dalla DW 0000H ;richiesta d'interruzione dalla porta seriale COM2 ;/---------------------------------------------------------------------------\ ;|Buffer Circolare destinato a raccogliere i dati in partenza per il Registro| ;|Dati in Trasmissione, nelle operazioni di acquisizione sotto Interruzione | ;\---------------------------------------------------------------------------/ ;\Contiene il puntatore alla prima posizione libera ;|del Buffer, cioŠ a quella in cui verr… collocato il ;|Dato da Trasmettere;si tratta comunque di un OFFSET ;|rispetto alla prima locazione del Buffer stesso e ;|all'inizio punta la locazione "TxD_Buf" (offs=00H); TxDBufWR DW 0000H ;|dopo che il dato Š stato collocato nel Buffer ;|(SCRITTURA operata dalla dalla procedura "TxD_Int") ;|il puntatore [TxDBufWR] viene incrementato di UNA ;|posizione e reinizializzato a 0000H, se necessario, ;/per ritornare a puntare l'inizio del Buffer ;\Contiene il puntatore al primo carattere da ;|rimuovere dal Buffer Circolare di Trasmissione; si ;|tratta comunque di un OFFSET rispetto alla prima ;|locazione del Buffer stesso e all'inizio punta la TxDBufRD DW 0000H ;|locazione "TxD_Buf" (offset=0000H); dopo ogni ;|LETTURA (operata dalla sottoprocedura "TxD_RD" di ;|"ServInt0B") il puntatore [TxDBufRD] viene incre- ;|mentato di UNA posizione e se necessario reinizia- ;|lizzato a 0000H per ritornare a puntare l'inizio ;/del Buffer ;\Per il "Buffer Circolare di Trasmissione" vengono ;|riservati 256 bytes; in esso verranno collocati i ;|bytes da spedire al "Registro di Trasmissione"; per TxD_Buf DB 256 DUP(" ");|la gestione del Buffer Circolare vengono utilizzati ;|2 puntatori [TxDBufRD] e [TxDBufWR]: se sono uguali ;|allora il Buffer E` VUOTO; se [TxDBufWR] lo supera ;/di un byte allora Š PIENO TxD_endW LABEL word ;\Identifica la locazione successiva all'ultima TxD_endB EQU this byte ;/prevista per il "Buffer Circolare di Trasmissione" ;\Questa variabile Š indispensabile per stabilire se ;|il dato da trasmettere pu• essere spedito diretta- TxD_Chk DB 00H ;|mente al Registro di Trasmissione (se 00, UART non ;|in attesa di dati) o se deve essere aggiunto in ;|coda al Buffer Circolare di Trasmissione (se a 01, ;/UART occupato a trasmettere) ;---------------------------------------------------- RxDBufWR DW 0000H ;\Variabili per il servizio di Interruzione generato RxDBufRD DW 0000H ;|da "Dato Pronto in Ricezione" RxD_Buf DB 256 DUP(" ");/ ;AREA DESTINATA ALLE PROCEDURE DEL PROGRAMMA ;/---------------------------------------------------------------------------\ ;| PROCEDURA : BARRA | ;| DESCRIZIONE : Stampa un'intera riga di spazi | ;\---------------------------------------------------------------------------/ BARRA: M_CURSOR DH,0 MOV AL,' ' MOV CX,80 bar0: CALL BIOchr1 LOOP bar0 RET ;/---------------------------------------------------------------------------\ ;| AREA DESTINATA ALLE PROCEDURE DEL PROGRAMMA | ;\---------------------------------------------------------------------------/ ;/---------------------------------------------------------------------------\ ;| PROCEDURA : DESKTOP | ;| DESCRIZIONE : Predispone il Piano di Lavoro per il Test Seriale e | ;| inizializza le Variabili necessarie per il programma di Test| ;| Se il valore ricevuto in ingresso in SI Š 0000H la porta| ;| seriale desiderata NON Š presente nel sistema; la procedura| ;| segnala l'errore e pone automaticamente fine al test,| ;| tornando al DOS (rientro a livello _OUT) con un artificio. | ;\---------------------------------------------------------------------------/ DESKTOP:PUSH SI ; In ingresso SI=0000 se la porta richiesta NON ; Š presente nel sistema... MOV Word Ptr CS:[Numero],01; Numero di Bytes trasmessi MOV AL,'°' ;\ M_COLOR 71H ;|Predispone il Piano di lavoro CALL Riempi ;|su tavola zigrinata CALL VIA_cur ;/ M_COLOR 70H ;\ MOV DH,0 ;| CALL BARRA ;| M_msgC Titolo, 0,12,70H;| M_COLOR 74H ;|Intestazione M_msgN Titolo1 ;/ MOV DH,24 ;\ CALL BARRA ;|Menu M_msgC MENU02,24,70,70H;| M_Chr 'Q',24,70,74H ;/ ;M_corn altezza,larghezza,riga,colonna,colore,tipo,ombra,salva M_corn 5 , 69 , 11 , 5 , 1EH , 01 , 01 ,1000H POP SI ;\ CMP SI,0000H ;| JNZ DESK_0 ;| M_msgC Nocom0,12,13,1FH;|Recupera il valore iniziale di SI; se vale 0 M_COLOR 9FH ;|la porta richiesta NON Š presente nel sistema; M_msgN Nocom1 ;|se SI contiene 0000 la porta NON Š installata: M_COLOR 1FH ;|si segnala l'errore e si termina senza test M_msgN Nocom2 ;| MOV AL,CS:[depPOR];|"La PORTA SERIALE desiderata, COM , ADD AL,30H ;| non Š disponibile" M_Chr AL,12,45,1EH ;| M_Chr AL, 0,61,74H ;| <<<< Visualizza anche nella barra del Titolo CALL KEYwait ;/ POP AX ;\NB: recupera con POP AX la posizione pendente JMP _OUT ;|nello stack dovuta alla chiamata "CALL DESKTOP ;/per poter tornare con JMP invece che con "RET" ;--------------------------------------------------------------------- DESK_0: M_msgC Tema0,12, 7,1FH;\Messaggio di test eseguibile M_msgC Tema1,14, 7,1FH;| MOV AL,CS:[depPOR];|"TRASMISSIONE SERIALE su COMx - ADD AL,30H ;| protocollo HW: 9600,N,2,8" M_Chr AL,12,43,1EH ;| M_Chr AL, 0,61,74H ;/ <<<< Visualizza anche nella barra del Titolo M_msgC MENU01,24,7,70H;\/--------------------------------------------\ M_Chr 'I',24, 7,74H ;||************ Primo Menu interno ************| DESK_1: CALL KEYwait ;|\--------------------------------------------/ AND AL,11011111B ;|Rimane in attesa dei tasti del Menu principale CMP AL,'I' ;| JZ DESK_2 ;| con "I" inizia il Test CMP AL,'Q' ;| con "Q" torna al DOS JNZ DESK_1 ;| JMP _OUT ;/ ;--------------------------------------------------------------------- DESK_2:M_msgC MENU06,24, 4,70H;\/--------------------------------------------\ M_Chr 'M',24,17,74H ;||********* Secondo Menu interno ************| M_Chr 'A',24,27,74H ;|\--------------------------------------------/ DESK_3: CALL KEYwait ;|Rimane in attesa dei tasti del Menu secondario AND AL,11011111B ;| MOV Byte Ptr CS:[DepoMod],00;| con "A" Trasmissione Automatica CMP AL,'A' ;| JZ DESKdati ;| MOV Byte Ptr CS:[DepoMod],01;| con "M" Trasmissione Manuale CMP AL,'M' ;| JNZ DESK_3 ;/ ;/-------------------------------------------------------------------\ ;|**** NB: prosegue attraverso DESKdati e termina con il suo RET ****| ;\-------------------------------------------------------------------/ ;/---------------------------------------------------------------------------\ ;| PROCEDURA : DESKdati | ;| DESCRIZIONE : Predispone il Piano di Ricetrasmissione DATI e inizializza | ;| le Variabili necessarie per il programma di Test | ;\---------------------------------------------------------------------------/ DESKdati: ; ;M_corn altezza,larghezza,riga,colonna,colore,tipo,ombra,salva M_corn 7 , 80 , 1 , 0 , 03H , 00 , 00 ,2000H M_Chr '[', 1, 3,03H ;|Menu M_COLOR 03H ;| Primo campo di emissione Dati seriali M_msgN Centro1 ;| [Caratteri Ascii TRASMESSI] M_COLOR 03H ;| MOV AL,']' ;| CALL BIOchr1 ;/ ;M_corn altezza,larghezza,riga,colonna,colore,tipo,ombra,salva M_corn 17 , 80 , 7 , 0 , 03H , 00 , 00 ,3000H M_Chr '[', 7, 3,03H ;| M_COLOR 03H ;| Secondo campo di emissione Dati seriali M_msgN Centro2 ;| [Bytes TRASMESSI] M_COLOR 03H ;| MOV AL,']' ;| CALL BIOchr1 ;/ M_Chr '*', 7, 0,03H ;\Caratteri per sovrapporre le due cornici M_Chr '*', 7,79,03H ;/ ;--------------------------------------------------------------------- ;/---------------------------------------------\ ;|Inizializza le variabili - Test Seriale| ;\---------------------------------------------/ MOV Byte Ptr CS:[DatTxD],00; Primo Carattere da trasmettere (ascii 00) MOV Byte Ptr CS:[RigAsci],02;\Predispone la riga e la colonna di stampa cor- MOV Byte Ptr CS:[ColAsci],01;|rente per i caratteri al valore 2,1 MOV Byte Ptr CS:[AtrAsci],0FH;/Colore da usare nella stampa dei caratteri MOV Byte Ptr CS:[RigByte],08;\Predispone la riga e la colonna di stampa cor- MOV Byte Ptr CS:[ColByte],01;|rente per i bytes al valore 8,1 MOV Byte Ptr CS:[AtrByte],0FH;/Colore da usare nella stampa dei bytes RET ;/---------------------------------------------------------------------------\ ;| PROCEDURA : Stampa | ;| DESCRIZIONE : Stampa i dati trasmessi dalla porta SERIALE, organizzandoli | ;\---------------------------------------------------------------------------/ Stampa: PUSH CX PUSH BX PUSH AX ;--------------------------------------------------------------------- PUSH AX ;\Posizione la colonna di stampa del numero di MOV DL,30 ;|bytes ricetrasmessi MOV AL,CS:[DepoMod];|Preleva il codice di Modo CMP AL,00H ;|[DepoMod]=00 con "A" Trasmissione Automatica JZ stamp ;|[DepoMod]=01 con "M" Trasmissione Manuale ADD DL,12 ;/ stamp: M_msgC BytTxd,24,DL,70H;\ M_COLOR 74H ;| MOV AX,CS:[Numero];|Stampa e mette a video il numero dei Bytes CALL Wor2Dec ;|trasmessi INC AX ;| MOV CS:[Numero],AX;| POP AX ;/ ;--------------------------------------------------------------------- ;/----[Valori Trasmessi: Caratteri Ascii]------\ ;| Primo campo di emissione Dati seriali | ;\---------------------------------------------/ MOV CL,CS:[AtrAsci];\ M_COLOR CL ;| MOV DH,CS:[RigAsci];|Assume la riga, la colonna e il colore di MOV DL,CS:[ColAsci];|stampa e mette a video il carattere Ascii CALL SET_cur ;|del valore trasmesso corrente CALL BIOchr1 ;/ INC DL ;\Controllo della Colonna corrente: se la stampa CMP DL,79 ;|Š ancora all'interno della cornice, sulla riga JNZ stamp0 ;/corrente, tutto va bene MOV DL,01 ;\Riporta la colonna di stampa all'interno della INC DH ;|cornice, sulla riga successiva, e controlla se CMP DH,7 ;|la nuova riga Š essa pure ancora all'interno JNZ stamp0 ;/della cornice; se Š cosŤ tutto va bene MOV DH,2 ;\La cornice Š stata riempita completamente con MOV CL,CS:[AtrAsci];|i caratteri in partenza dalla Seriale; le DEC CL ;|coordinate di stampa sono riportate nell'ango- CMP CL,0DH ;|lo in alto a sinistra all'interno della corni- JNZ stamp0 ;|ce e, per evidenziare la sovrascrittura, si MOV CL,0FH ;|cambia anche il colore di stampa, alternando stamp0: MOV CS:[AtrAsci],CL;/Bianco Brillante a Giallo,sempre in campo Nero MOV CS:[RigAsci],DH; MOV CS:[ColAsci],DL ;/--------[Valori Trasmessi: Bytes]------------\ ;| Secondo campo di emissione Dati seriali | ;\---------------------------------------------/ MOV CL,CS:[AtrByte];\ M_COLOR CL ;| MOV DH,CS:[RigByte];|Assume la riga, la colonna e il colore di MOV DL,CS:[ColByte];|stampa e mette a video la coppia di caratteri CALL SET_cur ;|ASCII corrispondenti del valore trasmesso CALL Byt2Asc ;/corrente ADD DL,3 ;\Controllo della Colonna corrente: se la stampa CMP DL,79 ;|Š ancora all'interno della cornice, sulla riga JNZ stamp1 ;/corrente, tutto va bene MOV DL,01 ;\Riporta la colonna di stampa all'interno della INC DH ;|cornice, sulla riga successiva, e controlla se CMP DH,23 ;|la nuova riga Š essa pure ancora all'interno JNZ stamp1 ;/della cornice; se Š cosŤ tutto va bene MOV DH,8 ;\La cornice Š stata riempita completamente con MOV CL,CS:[AtrByte];|i caratteri in partenza dalla Seriale; le DEC CL ;|coordinate di stampa sono riportate nell'ango- CMP CL,0DH ;|lo in alto a sinistra all'interno della corni- JNZ stamp1 ;|ce e, per evidenziare la sovrascrittura, si MOV CL,0FH ;|cambia anche il colore di stampa, alternando stamp1: MOV CS:[AtrByte],CL;/Bianco Brillante a Giallo,sempre in campo Nero MOV CS:[RigByte],DH; MOV CS:[ColByte],DL POP AX POP BX POP CX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : INIserial | ;|DESCRIZIONE: Seleziona automaticamente la porta seriale COM predisposta dal| ;| valore della costante "COM_num" (per default EQU 02H= COM2), e| ;| se la porta seriale desiderata NON Š presente nel sistema,| ;| lascia in uscita in SI il valore 0000H; altrimenti lascia in| ;| SI l'indirizzo Base dell'UART sotto controllo ([port_8]= 03F8H| ;| o 02F8H o 03E8H o 02E8H) e rende facilmente reperibili TUTTI i| ;| Registri della serie virtualizzandoli con altrettante variabili| ;| /------*-----*-----*-----*-----*-----------------------------\| ;| |******| COM1| COM2| COM3| COM4|Descrizione || ;| *------*-----*-----*-----*-----*-----------------------------*| ;| |port_8|03F8H|02F8H|03E8H|02E8H|Scritt/Lett DATO -LSBdivisore|| ;| |port_9|03F9H|02F9H|03E9H|02E9H|Abilitaz Interruz-MSBdivisore|| ;| |port_A|03FAH|02FAH|03EAH|02EAH|Identif interruzioni || ;| |port_B|03FBH|02FBH|03EBH|02EBH|Registro controllo LINEA || ;| |port_C|03FCH|02FCH|03ECH|02ECH|Registro controllo MODEM || ;| |port_D|03FDH|02FDH|03EDH|02EDH|Registro stato LINEA || ;| |port_E|03FEH|02FEH|03EEH|02EEH|Registro stato del MODEM || ;| \------*-----*-----*-----*-----*-----------------------------/| ;| Inizializza inoltre: | ;| a) la velocit… di ricetrasmissione caricando il divisore a 16| ;| bit, predisposto dalla costante "Baude" (default EQU 000CH=| ;| 9600 baud) nei Registri [port_9]=MSB e [port_8]=LSBdivisore| ;| b) il valore dei parametri desiderati per il protocollo HW, in| ;| in accordo con le scelte suggerite dalla costante "Protoc"| ;| (default EQU 07H= 8 bit di dato e 2 di stop,nessuna parit…)| ;| c) il valore del Registro di abilitazione delle Interruzioni,| ;| [port_9] Š fissato a 00H: in questo modo nessun evento se-| ;| riale produrr… richiesta d'interruzione sulla linea dedica-| ;| ta IRQ3 o IRQ4 e non sar… necessario predisporre la relati-| ;| va procedura di servizio (rispettivamente INT0BH o INT0CH) | ;| d) il valore del Registro di controllo MODEM, [port_C], Š fis-| ;| sato a 03H: in questo modo sono attivi i segnali di tipici| ;| del MODEM, "Data Terminal Ready" e "Request To Send" | ;\---------------------------------------------------------------------------/ depPOR DB COM_num ; Numero della porta COM da controllare (1, 2, 3 o 4) depVEL DW Baude ; Valore n del divisore di Baud RATE necessario per ; stabilire la velocitŕ di Ricetrasmissione = 115200Hz/n depTIP DB Protoc ; Byte ricostruito in accordo con il desiderato ; numero di bit di dato, di stop e di (eventuale) parit… ;/-----*-----*-----*-----*------------------------------\ ;| COM1| COM2| COM3| COM4|Descrizione | ;*-----*-----*-----*-----*------------------------------* port_8 DW ? ;|03F8H|02F8H|03E8H|02E8H|Scritt/Lett DATO - LSBdivisore| port_9 DW ? ;|03F9H|02F9H|03E9H|02E9H|Abilitaz Interruz- MSBdivisore| port_A DW ? ;|03FAH|02FAH|03EAH|02EAH|Identif interruzioni | port_B DW ? ;|03FBH|02FBH|03EBH|02EBH|Registro controllo LINEA | port_C DW ? ;|03FCH|02FCH|03ECH|02ECH|Registro controllo MODEM | port_D DW ? ;|03FDH|02FDH|03EDH|02EDH|Registro stato LINEA | port_E DW ? ;|03FEH|02FEH|03EEH|02EEH|Registro stato del MODEM | ;\-----*-----*-----*-----*------------------------------/ ;---------------------------------------------------------------------------- ;/------[PRIMA FASE]---------------------------------------------------------\ ;| Inizializzazione dei REGISTRI della PORTA SERIALE | ;\---------------------------------------------------------------------------/ INIserial: PUSH ES ;\Assume in AX l'indirizzo BASE della porta MOV AX,0000H ;|seriale suggerita dalla variabile [depPOR], MOV ES,AX ;|a sua volta predisposta con il valore della MOV SI,0400H ;|costante "COM_num" (per default EQU 02H=COM2), MOV AL,CS:[depPOR];|estraendolo dalle locazioni dell'Area di comu- DEC AL ;|nicazione BIOS: le prime sue 8 locazioni sono SHL AL,1 ;|predisposte in fase di bootstrap ai valori: MOV AH,00H ;| /-------------------------------------------\ ADD SI,AX ;| |0000:0400H - Porta Seriale 1 (COM1) 03F8H | MOV AL,ES:[SI] ;| |0000:0402H - Porta Seriale 2 (COM2) 02F8H | INC SI ;| |0000:0404H - Porta Seriale 3 (COM3) 03E8H | MOV AH,ES:[SI] ;| |0000:0406H - Porta Seriale 4 (COM4) 02E8H | POP ES ;| \-------------------------------------------/ ;/se tutte i possibili UART sono presenti... CMP AX,0000H ;\ JNZ INIse_ ;|Se AX contiene 0000 la porta desiderata NON Š MOV SI,AX ;|installata: si torna immediatamente con SI=0 RET ;/ ;--------------------------------------------------------------------- INIse_: MOV CS:[port_8],AX;\ INC AX ;|Altrimenti inizializza le 7 variabili che MOV CS:[port_9],AX;|saranno utilizzate per individuare i Registri INC AX ;|della porta seriale desiderata; per la COM2: MOV CS:[port_A],AX;| INC AX ;|[port_8]=02F8H Registro Scrittura/Lettura DATO MOV CS:[port_B],AX;|[port_9]=02F9H Abilitazione interruzioni INC AX ;|[port_A]=02FAH Identificatore interruzioni MOV CS:[port_C],AX;|[port_B]=02FBH Registro di controllo LINEA INC AX ;|[port_C]=02FCH Registro di controllo MODEM MOV CS:[port_D],AX;|[port_D]=02FDH Registro di stato linea seriale INC AX ;|[port_E]=02FEH Registro stato MODEM MOV CS:[port_E],AX;/ ;/------[SECONDA FASE]-------------------------------------------------------\ ;| Inizializzazione della VELOCITA` di RICETRASMISSIONE SERIALE | ;\---------------------------------------------------------------------------/ ;\/-[port_B]-----------------------------------\ ;|| Registro di controllo della LINEA | ;|\--------------------------------------------/ ;|Inizia la programmazione dell'UART: per poter MOV DX,CS:[port_B];|accedere ai registri divisori di BaudRate Š MOV AL,80H ;|necessario anzitutto porre a "1" il bit7 OUT DX,AL ;|di [port_B]: con questa predisposizione ;|possono ora essere introdotti i corretti ;|valori per il divisore di baud rate: ;| "Baud Rate-lo", su [port_8] e ;/ "Baud Rate-hi", su [port_9] ;\/--------------------------------------------\ ;|| AX= fattore di divisione [115200/costante] | ;|\--------------------------------------------/ ;|Prepara in AX (AL=LSB, AH=MSD) la costante di ;|divisione necessaria per dividere il clock ad ;|alta frequenza (115200Hz) fornito all'UART (a ;|partire dalla frequenza di norma applicata, di ;|1.8432 MHz, LOCALMENTE predivisa per 16) al ;|fine di garantire la desiderata velocit… di ;|RICE-TRASMISSIONE (es: 9600 bps = 9600 baud) ;|/--------------------------------------------\ ;||Il valore del divisore a 16 bit Š suggerito| MOV AX,CS:[DepVEL];||dalla variabile [DepVel], a sua volta predi-| ;||sposta con il valore della costante "Baude"| ;||(default EQU 000CH=9600 baud) | ;|\--------------------------------------------/ ;|Si ricorda che l'UART contiene un generatore ;|programmabile di BAUD RATE in grado di tratta- ;|re qualunque frequenza da 0 a 3.1 MHz; normal- ;|mente la frequenza applicata Š di 1.8432 MHz ;|o, talvolta, quella due terzi pi— grande, ;|3.072 MHz), su cui viene operata immediatamen- ;|te una predivisione per 16, cosicch‚ la co- ;|stante descritta andr… a dividere effettiva- ;|mente la frequenza di 115200 Hz, generando la ;/desiderata frequenza di ricetrasmissione ;\/-[port_8]-----------------------------------\ ;|| Registro divisore Baud RATE (parte bassa) | MOV DX,CS:[port_8];|\--------------------------------------------/ OUT DX,AL ;|Se su [port_B] il bit7="1" la porta [port_8] ;/serve come Registro divisore Baud RATE (low) ;\/-[port_9]-----------------------------------\ MOV AL,AH ;|| Registro divisore Baud RATE (parte alta) | MOV DX,CS:[port_9];|\--------------------------------------------/ OUT DX,AL ;|Se su [port_B] il bit7="1" la porta [port_9] ;/serve come Registro divisore Baud RATE (high) ;/-[NB]----------------------------------------\ ;|se invece su [port_B] il bit7="0" la prima| ;|porta [port_8] serve come BUFFER di trasmis-| ;|sione (in LETTURA) o di ricezione (in SCRIT-| ;|TURA) e la seconda porta [port_9] serve come| ;|Registro di Abilitazione Interruzioni | ;\---------------------------------------------/ ;/------[TERZA FASE]---------------------------------------------------------\ ;| Inizializzazione delle CARATTERISTICHE di RICETRASMISSIONE SERIALE | ;\---------------------------------------------------------------------------/ ;\/-[port_B]-----------------------------------\ ;|| Registro di controllo della LINEA | ;|\--------------------------------------------/ ;|Viene ricostruito il byte da spedire alla por- ;|ta [port_B], che rappresenta le caratteristi- ;|che desiderate, cioŠ il Numero di bit per DATO ;|il Numero di bit di STOP e la presenza del Bit ;|di Parit…; poich‚ la programmazione della ;|velocit… di RICETRASMISSIONE Š gi… stata ;|eseguita Š necessario anche riporre a "0" il ;|bit7 di tale byte;di norma si pone a "0" anche ;|il bit6 (se ="1", impostazione di break, il ;|dato di output seriale Š forzato alla condi- ;|zione di SPACE (0 logico) indipendentemente da ;|ci• che l'UART intende trasmettere) e il bit5 ;|(se = "1" il bit di parit… viene forzato ad un ;|valore costante, in funzione della programma- ;|zione dei bit4/bit3; altrimenti il bit di ;|parit… conserva il suo significato) ;|/--------------------------------------------\ ;||La combinazione di bit corrispondente alle| MOV DX,CS:[port_B];||nostre esigenze Š suggerita dalla variabile| MOV AL,CS:[DepTIP];||[DepTip], a sua volta predisposta con il va-| OUT DX,AL ;||lore della costante "Protoc" (default EQU 07| ;||= 8 bit di dato e 2 di stop, nessuna parit…)| ;|\--------------------------------------------/ ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[port_B]| 0 | 0 | 0 | x | 0 | 1 | 1 | 1 | 07H ;| \---*---*---*---*---*---*---*---/ ;|Protocollo/ | | | | | \---*-8 dato ;|Break disab.--/ | | | \-----2 bit stop ;/Parit… disab.-----/ \---*-----nessuna parit… ;/------[QUARTA FASE]--------------------------------------------------------\ ;| Inizializzazione del REGISTRO di CONTROLLO del MODEM | ;\---------------------------------------------------------------------------/ ;\/-[port_C]-----------------------------------\ ;|| Registro di controllo del MODEM | ;|\--------------------------------------------/ ;|Normalmente il Registro di MODEM va inizializ- ;|zato a 03H e poi non si tocca pi—; tale predi- ;|sposizione bit0 e bit1 a "1") attiva i segnali ;|di controllo tipici del MODEM, "Data Terminal ;|Ready" e "Request To Send": in questo modo il ;|il computer DTE (UART) avvisa il modem DCE che ;|Š regolarmente collegato alla linea di comuni- ;|cazione, che Š pronto a trasmettere o ricevere ;|dati (DTR) e che dispone di dati ed č pronto a ;|trasmetterglieli (RTS): il bit2 OUT1 di questo ;|registro (uscita ausiliaria destinata utente) ;|non Š usato, mentre il bit3 (OUT2=altra uscita ;|ausiliaria destinata utente) DEVE essere posta MOV DX,CS:[port_C];|a "1" solo se si desidera consentire al- MOV AL,03H ;|l'INTERRUZIONE generata dall'UART di raggiun- OUT DX,AL ;|gere il bus del sistema (per essere eventual- ;|mente controllata dal gestore delle interru- ;|zioni, 8259); infine il bit4 deve essere a 0, ;|in condizioni normali; se forzato a 1 la porta ;|seriale (UART) si pone in uno stato molto par- ;|ticolare, LookBack Mode, straordinariamente ;|utile per collaudare i nostri programmi ma del ;|tutto inopportuno in regolare ricetrasmissione ;|i bit5, bit6 e bit7 sono sempre a 0 (non usati ;|da nessuna versione di UART) ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[port_C]| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 03H ;| \---*---*---*---*---*---*---*---/ ;|non usati-*---*---/ | | | | \DTR on ;|no LookBack Mode------/ | | \----RTS on ;/INT disabilitate----OUT2--/ \OUT1-non usata ;/------[QUINTA FASE]--------------------------------------------------------\ ;| Inizializzazione di ABILITAZIONE delle INTERRUZIONI SERIALI | ;\---------------------------------------------------------------------------/ ;\/-[port_9]-----------------------------------\ ;|| Registro di abilitazione delle INTERRUZIONI| ;|\--------------------------------------------/ ;|Vengono specificati solo gli eventi che si ;|desidera utilizzare per innescare il meccani- ;|smo dell'interruzione, in grado di attivare la ;|linea IRQ3/IRQ4 dedicata all'UART coinvolto, ;|avvisando cosŤ il controllore delle interru- ;|zioni 8259 che far… partire la relativa proce- ;|dura di servizio BIOS, INT 0BH o INT 0CH; se ;|NON SI DESIDERA far riferimento alle tecniche ;|d'interruzione tutti i bit di questo registro ;|sono lasciati a 0; altrimenti i bit significa- MOV DX,CS:[port_9];|tivi sono: bit0="1" abilita interrupt quando MOV AL,00H ;|c'Š un DATO PRONTO in RICEZIONE; bit1="1" abi- OUT DX,AL ;|lita interrupt quando il registro di TRASMIS- RET ;|SIONE Š VUOTO (DATO TRASMESSO); il bit2="1" ;|abilita interrupt se il registro di stato non ;|Š pi— a 00H (ERRORI in RICEZIONE o RICEVUTA ;|condizione di BREAK); il bit3="1" abilita un ;|interrupt per cambiamento dello stato del ;|MODEM. Se su [port_B] il bit7="0" la porta ;|[port_9] serve come Registro di Abilitazione ;|delle Interruzioni: con i bit7öbit4 tutti a ;|"0" tutte le interruzioni da parte della ;|SERIALE sono disabilitate ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[port_9]| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 00H ;| \---*---*---*---*-no*-no*-no*-no/ ;|non usati-*---*---*---/ | | | | RxD ;|Variazione Stato Linea----/ | | \-pieno ;/Variazione Registro Modem-----/ \-TxD vuoto ;/---------------------------------------------------------------------------\ ;| /----------------------------------------------\| ;|PROCEDURA : SetInt0B |** VERSIONE per IRQ3 da Trasmettitore Vuoto **|| ;| \----------------------------------------------/| ;|DESCRIZIONE: Questa procedura predispone il computer per accettare le| ;| richieste d'interruzione generate dalla porta seriale COM2. | ;|/-----------\ | ;|| | Questa versione abilita la richiesta di interruzione SOLO in| ;|| NB: | caso di "Registro Trasmettitore Vuoto"; ogni modifica va| ;|| | operata sulla riga di programma con l'etichetta: "Cambia". | ;|\-----------/ | ;| Per rendere disponibile una procedura di servizio per le| ;| richieste d'interruzione generate dalla porta seriale COM2 Š| ;| necessario rimappare il vettore INT 0BH chiamato a puntarla;| ;| per poter ripristinare in uscita le stesse condizioni trovate| ;| in ingresso, prima di sostituirlo, salva il valore del vettore| ;| originale. | ;| Interviene sia sui registri dell'UART (azzerando le richieste| ;| d'interruzione pendenti e abilitando solo gli eventi seriali| ;| autorizzati a interrompere, nel nostro esempio dal ricevitore| ;| e dal trasmettitore) sia sul controller delle interruzioni del| ;| computer (il PIC 8259A). | ;| Sebbene sia cosa consiglibile la procedura non provvede al| ;| servizio di errori critici e di break: in queste condizioni la| ;| pressione dei tasti ctrl-C o ctrl-Break imporrŕ un ritorno al| ;| DOS senza ripristinare il vettore INT 0BH originale. | ;\---------------------------------------------------------------------------/ SetInt0B: ;\La sostituzione di un Vettore Š operazione CLI ;|critica, per cui per tutto il tempo necessario ;/le interruzioni sono disabilitate PUSH ES ;\ XOR AX,AX ;| MOV ES,AX ;| MOV DI,002CH ;|Punta con ES:DI la locazione 0000:0030H, LEA SI,Old_Int0B ;|contenente il vettore originale INT 0BH per il MOV AX,ES:[DI] ;|servizio dell'interruzione IRQ3 da COM2 o COM4 MOV CS:[SI],AX ;|e con CS:SI la variabile locale [Old_Int0B], ADD DI,2 ;|nella quale riporne il valore, in attesa di ADD SI,2 ;|ripristinarlo, alla fine del programma MOV AX,ES:[DI] ;| MOV CS:[SI],AX ;/ MOV AX,CS ;\Sostituisce nelle medesime locazioni della MOV ES:[DI],AX ;|Tabella dei Vettori (i 4 bytes a partire da SUB DI,2 ;|0000:002CH ancora puntati da ES:DI) il vettore LEA AX,ServInt0B ;|originale INT 0BH con CS:ServInt0B, indirizzo MOV ES:[DI],AX ;|del nuovo servizio per l'interuzione IRQ3 da POP ES ;/COM2 o COM4 ;\La lettura dei 2 Registri di Stato dell'UART MOV DX,CS:[port_D];|(quello di Linea, [port_D] e quello del Modem, IN AL,DX ;|[port_E]) annulla tutti i bit in essi contenu- MOV DX,CS:[port_E];|ti, annullando cosŤ anche le possibili richie- IN AL,DX ;|ste d'interruzione pendenti per errori in ;/ricezione o per presenza di CTS, DSR o RI MOV DX,CS:[port_A];\La lettura del Registro Identificatore di IN AL,DX ;|Interrupt, [port_A], annulla anche l'eventuale ;/suo bit0 (se bit0=1 significa INT pendente) MOV DX,CS:[port_8];\La lettura del Registro di Ricetrasmissione, IN AL,DX ;|[port_8], annulla l'eventuale richiesta di ;/interrupt per "dato seriale disponibile" ;\Per poter abilitare con sicurezza gli eventi MOV DX,CS:[port_B];|seriali autorizzati ad interrompere č necessa- IN AL,DX ;|rio essere certi che l'indirizzo [port_9] stia AND AL,01111111B ;|puntando il Registro di Abilitazione delle OUT DX,AL ;|Interruzioni e NON uno dei 2 Registri Divisori ;|di Baud Rate, ponendo a 0 il bit7 del Registro ;/di Controllo Linea, [port_B] ; ;\Stabilisce gli eventi seriali autorizzati a ; ;|richiedere servizio d'interruzione, ponendo a ; NB: cambia qui gli eventi ;|1 i bit ad essi associati, nel Registro di ; che possono interrompere.. ;|Abilitazione delle Interruzioni, [port_9]: ; |||| ;| /-7-6-5-4-*-3-*-2-*-1-*-0-\ Cambia: MOV AL,00000010B ;|[port_9]| 0 0 0 0 | 0 | 0 | 1 | 0 | 02H MOV DX,CS:[port_9];| \---------*-no*-no*-si*-no/ OUT DX,AL ;|Variaz. Stato Linea-/ | | \- Dato pronto ; ;|Variaz. Stato Modem-----/ | in Ricezione ; ;|Dato trasmesso,Trasm. vuoto-/ ; ;|I bit degli eventi non autorizzati ad inter- ; ;/rompere DEVONO essere lascati a 0 logico ;\Per poter rendere possibili le interruzioni da ;|parte dell'UART Š necessario forzare a 1 la ;|linea OUT2 (pin31 UART); questa situazione si ;|ottiene portando a 1 il bit3 del Registro di ;|Controllo Modem, [port_C] e permette il colle- MOV AL,00001011B ;|gamento a livello hardware della linea INTR MOV DX,CS:[port_C];|(pin30 dell'UART) alla linea IRQ4 del control- OUT DX,AL ;|ler delle interruzioni, 8259A; in condizioni ;|normali anche le linee DTR (pin33 UART) e RTS ;|(pin32 UART) devono essere attive (cioŠ a 1) ;|per cui saranno a 1 anche i rispettivi bit0 ;|e bit1, mentre il bit4 (Lookback Mode) deve ;|essere ovviamente a 0 ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[port_C]| 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0BH ;| \---*---*---*---*---*---*---*---/ ;|non usati-*---*---/ | | | | \DTR on ;|no LookBack Mode------/ | | \----RTS on ;/INT abilitate ----OUT2--/ \OUT1-non usata ;\Non rimane ora che intervenire sul controller ;|delle interruzioni del computer (il PIC 8259A) ;|per settare il bit corrispondente a COM2, nel IN AL,_8259mk ;|suo Registro di Abilitazione Interruzioni HW, MOV CS:[Dep8259],AL;|[0021H]. La linea IRQ3 (in arrivo da COM2) Š AND AL,11110111B ;|abilitata forzando a 0 il bit3; la tecnica OUT _8259mk,AL ;|utilizzata non altera i valori degli altri bit ;|di questo Registro, lasciando abilitate altre ;|eventuali fonti di interruzione (di solito ;|almeno il Timer di Sistema e la Tastiera). Una ;|copia dello stato originale di questo Registro ;|Š salvata nella variabile locale [Dep8259], in ;|attesa di ripristinarlo alla fine del programm ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[0021H]| 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | F4H ;| \-no*-no*-no*-no*-si*-no*-si*-si/ TIMER ;|LPT1 IRQ7-/ | | | | | | \---IRQ0 ;|DISK IRQ6-----/ | | | | \--IRQ1 KEYB ;|LPT2 IRQ5---------/ | | \------IRQ2 USER ;/COM1 IRQ4-------------/ \----------IRQ3 COM2 RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : OldInt0B | ;|DESCRIZIONE: Questa procedura ripristina le condizioni presenti nel sistema| ;| prima dell'esecuzione del nostro programma, chiamato a soddi-| ;| sfare le richieste d'interruzione generate dalla porta seriale| ;| (UART) COM2; recupera il valore del vettore INT 0BH originale| ;| e interviene sul Registro UART e su quello del controller| ;| delle interruzioni del computer (PIC 8259A) per impedire la| ;| possibilit… d'interruzione IRQ3 da parte della COM2. | ;\---------------------------------------------------------------------------/ OldInt0B: ;\Il ripristino di un Vettore Š operazione CLI ;|critica, per cui per tutto il tempo necessario ;/le interruzioni sono disabilitate ;\Per impedire all'UART di generare richieste HW ;|di interruzione Š necessario forzare a "0" la ;|sua linea OUT2 (pin31 UART); questa situazione ;|si ottiene portando a 0 il bit3 del Registro ;|di Controllo Modem [port_C],cosa che impedisce MOV DX,CS:[port_C];|il collegamento a livello hardware della linea IN AL,DX ;|INTR (pin30 dell'UART) alla linea IRQ4 del AND AL,00000011B ;|controller delle interruzioni, 8259A; in OUT DX,AL ;|condizioni normali le linee DTR (pin33 UART) e ;|RTS (pin32 UART) devono essere attive (cioŠ a ;|1) per cui anche i rispettivi bit0 e bit1 ;|saranno lasciati al loro valore originale ;|(presumibilmente a 1); il bit4 viene comunque ;|forzato a 0 (normale, no Lookback Mode) ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[port_C]| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 03H ;| \---*---*---*---*---*---*---*---/ ;|non usati-*---*---/ | | | | \DTR on ;|no LookBack Mode------/ | | \----RTS on ;/INT disabilitate ---OUT2--/ \OUT1-non usata ;\Si interviene sul controller delle interru- ;|zioni del computer (il PIC 8259A) per annulare ;|il bit corrispondente a COM2, nel suo Registro ;|di Abilitazione Interruzioni HW, [0021H]. La ;|linea IRQ3 (in arrivo da COM2) Š disabilitata MOV AL,CS:[Dep8259];|forzando a 1 il bit3; la tecnica utilizzata OR AL,00001000B ;|recupera lo stato originale di questo Registro OUT _8259mk,AL ;|prima dell'azione del nostro programma, recu- ;|perandolo dalla variabile locale [Dep8259], ;|mantenedo cosŤ inalterati i valori degli altri ;|bit e quindi le fonti di interruzione attive ;|in origine (di solito almeno il Timer di ;|Sistema e la Tastiera) ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[0021H]| 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | FCH ;| \-no*-no*-no*-no*-no*-no*-si*-si/ TIMER ;|LPT1 IRQ7-/ | | | | | | \---IRQ0 ;|DISK IRQ6-----/ | | | | \--IRQ1 KEYB ;|LPT2 IRQ5---------/ | | \------IRQ2 USER ;/COM1 IRQ4-------------/ \----------IRQ3 COM2 PUSH ES ;\ XOR AX,AX ;| MOV ES,AX ;| MOV DI,002CH ;|Punta con ES:DI la locazione 0000:002CH, LEA SI,Old_Int0B ;|contenente il nostro vettore CS:ServInt0B per MOV AX,CS:[SI] ;|il servizio INT 0BH dell'interuzione IRQ3 da MOV ES:[DI],AX ;|COM2 o COM4, e con CS:SI la variabile locale ADD DI,2 ;|[Old_Int0B], nella quale Š riposto il valore ADD SI,2 ;|del vettore originale, per diripristinarlo MOV AX,CS:[SI] ;| MOV ES:[DI],AX ;| POP ES ;/ RET ;/---------------------------------------------------------------------------\ ;| /----------------------------------------------\| ;|PROCEDURA : ServInt0B |** VERSIONE per IRQ3 da Trasmettitore Vuoto **|| ;| \----------------------------------------------/| ;|DESCRIZIONE: Procedura di servizio in risposta all'attivazione della linea| ;| d'interruzione IRQ3 generata da uno dei numerosi eventi| ;| seriali associati alla porta COM2. | ;|/-----------\ | ;|| | Questa versione provvede SOLO al servizio delle interruzioni| ;|| | generate dal "Registro di Trasmissione Vuoto" ma dispone del| ;|| | codice necessario a soddisfare anche le richieste dovute a| ;|| | "Dato Pronto in Ricezione"; negli altri 2 casi (variazione| ;|| | dei 2 Registri di Stato, della Linea e del Modem) si limita| ;|| | ad azzerare la richiesta dell'interruzione senza provvedere a| ;|| NB: | nessun altro servizio. | ;|| | In ogni caso ciascuno dei possibili eventi seriali dovr…| ;|| | essere autorizzato ad interrompere fissando a 1 SOLO i bit ad| ;|| | essi relativi nel "Registro di Abilitazione Interruzioni",| ;|| | [port_9]), operata sulla riga di programma con l'etichetta| ;|| | "Cambia", dentro la Procedura "SetInt0B" (vedi sotto). | ;|\-----------/ | ;| Per stabilire quale evento deve essere servito Š necessario| ;| assumere un codice dal Registro di Identificazione Interrupt| ;| [port_A]; se il suo bit0 Š 0 significa che c'Š un'interruzione| ;| pendente, cioŠ uno o pi— eventi hanno indotto l'UART della| ;| porta COM2 a generare una richiesta che non Š stata ancora| ;| stata servita (o servita del tutto) dal processore. Il compito| ;| di stabilire quale dei possibili 4 eventi Š in attesa Š affi-| ;| dato ai bit2/bit1: | ;| bit2/bit1=11 massima priorita per "Variazione del Registro di Stato| ;| della Linea",[port_D]: durante la ricezione di dati Š stata| ;| rilevata la presenza di errori (di sovrapposizione, di| ;| parit… o di composizione) o la presenza di segnale di break| ;| bit2/bit1=10 seconda priorit… per "Dato pronto in Ricezione" | ;| bit2/bit1=01 terza priorit… per "Trasmettitore vuoto" | ;| bit2/bit1=00 minima priorit… per "Variazione del Registro di Stato del| ;| Modem", [port_E]: durante la comunicazione Š stata rilevata| ;| la variazione di segnali in arrivo, come Carrier Detect(CD)| ;| Ring Indicator(RI) Data Set Ready(DSR) e Clear To Send(CTS)| ;| | ;| Maggiori dettagli sulle cause che hanno generato questi eventi| ;| sono disponibili nella sezione dedicata alla porta seriale sul| ;| sito **** www.giobe2000.it **** | ;\---------------------------------------------------------------------------/ ServINT0B: PUSH AX PUSH BX PUSH DX Riprova:MOV DX,CS:[port_A];\/76543*210\ <<<< bit di [port_A] ;|| |XX1|Nessuna richiesta di INT pendente ;|| |110|Variazione Registro Stato Linea ;|| |100|Dato pronto in Ricezione ;|| |010|Trasmettitore vuoto ;|| |000|Variazione Registro Stato Modem ;|\-----*---/ IN AL,DX ;|Controlla il bit0 del Registro di Identifica- TEST AL,00000001B ;|zione Interrupt, [port_A] e, se Š 1, significa JZ Chk_Int ;|che nessuna interruzione risulta pendente: la ;/procedura di servizio viene subito terminata!! ; /--------------------------------------------------------------------\ ; |Uscita dal Servizio d'Interruzione richiesto dalla porta seriale | ; |--------------------------------------------------------------------| ; |Non ci sono pi— richieste pendenti; ogni procedura di "servizio IRQ"| ; |come questa deve segnalare la sua fine spedendo il Controller delle| ; |Interruzioni del computer (PIC 8259A) il codice "EOI" (End Of Inter-| ; |rupt) per azzerarlo, in vista delle prossime interruzioni. | ; \--------------------------------------------------------------------/ MOV AL,20H ;\Segnala al Registro di Comando del Controller OUT _8259ct,AL ;|Interruzioni 8259A la fine della procedura di ;/servizio INT spedendo 20H,EOI,End Of Interrupt ;\Di norma al termine della procedura di servi- ;|zio di una INTERRUZIONE deve essere riabilita- ;STI ;|ta la possibilit… di interrompere la CPU in ;|modo MASCHERABILE da parte delle periferiche ;/autorizzate, con l'istruzione "STI" POP DX ;Ritorna dall'interruzione POP BX POP AX IRET ;----------------------------------------------------------------------------- ;\NB: la successiva verifica dei 2 bit di ID ha ;|ovviamente senso solo se la Procedura SetInt0B Chk_Int:AND AL,00000111B ;|ha autorizzato il possibile evento seriale ad ;|interrompere il processore, cioŠ SOLO se i ;|relativi bit del Registro di Abilitazione ;/Interruzioni, [port_9], sono stati fissati a 1 CMP AL,00000100B ;\Interrupt per Dato Pronto in Ricezione JE RxD_WR ;|... vai al Servizio CMP AL,00000010B ;|Interrupt per Trasmettitore Vuoto JE TxD_RD ;|... vai al Servizio CMP AL,00000110B ;|Interrupt per Variazione Registro Stato Linea JE StatLin ;/... vai al Servizio ; /--------------------------------------------------------------------\ ; |Servizio per Variazione Registro Stato Modem | ; |--------------------------------------------------------------------| ; |In uscita dalla precedente verifica non pu• che essere AL=00000000B;| ; |comunque questo codice non dovrebbe mai essere eseguito, dato che| ; |l'evento che dovrebbe richiederlo NON Š stato abilitato ad interrom-| ; |pere; il servizio assicurato, nel caso di Variazione del Registro di| ; |Stato del Modem, consiste nella lettura del registro stesso, opera-| ; |zione che azzera tutte le interruzioni pendenti da esso dipendenti. | ; |Se fosse abilitata il Servizio sarebbe attivato dopo ogni variazione| ; |dei segnali in arrivo, come CD (Carrier Detect, Ring Indicator (RI),| ; |Data Set Ready (DSR) e Clear To Send (CTS) | ; \--------------------------------------------------------------------/ StatMod:MOV DX,CS:[port_E];\La lettura del Registro di Stato del Modem, IN AL,DX ;|[port_E], annulla tutti i bit in esso contenu- JMP Riprova ;|ti, annullando cosŤ anche le possibili richie- ;|ste d'interruzione pendenti per presenza di ;/CTS, DSR o RI ; /--------------------------------------------------------------------\ ; |Servizio per Variazione Registro Stato Linea | ; |--------------------------------------------------------------------| ; |Comunque questo codice non dovrebbe mai essere eseguito, dato che| ; |l'evento che dovrebbe richiederlo NON Š stato abilitato ad interrom-| ; |pere; il servizio assicurato, nel caso di Variazione del Registro di| ; |Stato della Linea consiste nella lettura del registro stesso, opera-| ; |zione che azzera tutte le interruzioni pendenti da esso dipendenti. | ; |Se fosse abilitata il Servizio sarebbe attivato se, durante la| ; |ricezione di dati fosse stata rilevata la presenza di errori (di| ; |sovrapposizione, di parit… o di composizione) o la presenza di un| ; |segnale di break | ; \--------------------------------------------------------------------/ StatLin:MOV DX,CS:[port_D];\La lettura del Registro di Stato della Linea, IN AL,DX ;|[port_D], annulla tutti i bit in esso contenu- JMP Riprova ;|ti, annullando cosŤ anche le possibili richie- ;|ste d'interruzione pendenti per errori in ;/ricezione o per presenza di segnale di Break ; /--------------------------------------------------------------------\ ; |Servizio per Dato Pronto in Ricezione (per "SCRIVERE" il Buffer RxD)| ; | /-------------------------------------------------------------\ | ; | |NB: Comunque questo codice non dovrebbe mai essere eseguito,| | ; | | dato che l'evento che dovrebbe richiederlo NON Š stato| | ; | | abilitato ad interrompere; Š disponibile per completezza!| | ; | \-------------------------------------------------------------/ | ; |Questo Servizio assume il Dato Pronto dal Registro di Ricezione e lo| ; |inserisce nella prima locazione libera del Buffer Circolare di| ; |Ricezione; naturalmente viene garantita la circolarit… del Buffer,| ; |lasciando aggiornato il puntatore [RxDBufWR] di scrittura (cioŠ| ; |incrementandolo di 1 dopo l'aggiunta del byte), in modo da puntare| ; |sempre la successiva locazione disponibile ad ospitare l'eventuale| ; |successivo Dato Pronto; se necessario [RxDBufWR] viene reinizializ-| ; |zato per tornare a puntare l'inizio del Buffer, tenendo presente che| ; |esso Š in realt… un offset riferito all'inizio del Buffer, cioŠ (nel| ; |nostro caso) di valore compreso tra 0 e 255. | ; |La lettura dei bytes del Buffer Circolare di Ricezione Š esercitata| ; |da una procedura dedicata, "RxD_Int", dotata del proprio puntatore| ; |[RxDBufRD] di lettura. | ; |Durante la Gestione del Dato Pronto (operazione critica) si deve| ; |essere certi che le interruzioni siano disabilitate, cosa di solito| ; |assicurata per default dalle normali procedure di servizio delle INT| ; \--------------------------------------------------------------------/ RxD_WR: MOV DX,CS:[port_8];\Legge il Dato Pronto dal Registro di Ricezione IN AL,DX ;/ ;/---------------------------------------------\ ;| SCRITTURA nel Buffer Circolare di Ricezione | ;\---------------------------------------------/ MOV BX,CS:[RxDBufWR];\Predispone in BX il puntatore alla prima loca- MOV CS:[RxD_Buf+BX],AL;|zione del Buffer disponibile a ricevere nuovi ;|bytes e vi inserisce il Dato Pronto appena ;/letto dal Registro di Ricezione, [port_8] ;\Predispone il puntatore di SCRITTURA alla lo- INC BX ;|cazione successiva del Buffer (la prima dispo- CMP BX,256 ;|nibile a ricevere il prossimo carattere) e se JC RxD_W1 ;|viene a coincidere con la fine fisica del MOV BX,0000H ;|Buffer, esso viene reinizializzato a 0000H per ;/garantire la circolarit… ;\Se per qualche ragione la procedura di LETTURA ;|"RxD_Int", non Š stata in grado di "scaricare" ;|i bytes del Buffer [cosa molto improbabile se ;|la lettura viene esercitata regolarmente] i 2 RxD_W1: CMP BX,CS:[RxDBufRD];|puntatori del Buffer Circolare di Ricezione JZ RxD_W2 ;|coincidono indicando che il Buffer Š PIENO: in ;|questo caso il carattere appena letto viene ;/perduto (non essendoci per esso pi— spazio) ;\Comunque, prima di tornare il valore del nuovo MOV CS:[RxDBufWR],BX;|puntatore viene memorizzato nella variabile ad ;/esso dedicata RxD_W2: JMP Riprova ; Torna in attesa di altri interrupts seriali ; /--------------------------------------------------------------------\ ; |Servizio per Trasmettitore Vuoto (per "LEGGERE" il Buffer TxD)| ; |--------------------------------------------------------------------| ; |Questo Servizio Š attivato in risposta alla richiesta d'Interruzione| ; |per "Registro di Trasmissione Vuoto" cioŠ quando l'UART Š in attesa| ; |di dati da spedire sulla linea seriale; l'operazione Š pi— complessa| ; |da gestire, rispetto al Servizio per "Dato Pronto in Ricezione", nel| ; |quale ogni dato ricevuto Š comunque scritto nel Buffer di Ricezione| ; |quando arriva dalla porta, in modo assolutamente asincrono e non| ; |dipendente dalla procedura chiamata ad estrarlo dal medesimo Buffer.| ; |Se il Servizio per "Registro TxD Vuoto" dovesse comunque accedere al| ; |"Buffer di Trasmissione" per estrarne un byte, se esso fosse vuoto a| ; |sua volta, si rischia di tornare senza scrivere nulla nel Registro. | ; |In questo modo la richiesta rimane senza servizio e non potr… essere| ; |rinnovata neanche quando saranno aggiunti altri dati al Buffer di| ; |Trasmissione; la cosa pu• succedere se la porta seriale eroga dati| ; |con velocit… maggiore di quella con cui il programma Š in grado di| ; |produrli. | ; |Dunque se sono vuoti sia "Registro TxD" che "Buffer di Trasmissione"| ; |la procedura "TxD_Int" (che fornisce il dato da trasmettere) eviter…| ; |di aggiungerlo al Buffer e lo scriver… direttamente nel Registro;| ; |per prendere questa decisione dovr… essere in stretta sintonia con| ; |la procedura che stiamo progettando (chiamata a togliere i dati dal| ; |Buffer) e coordinare con essa le attivit… con l'aiuto di una flag| ; |condivisa, il contenuto della variabile [TxD_Chk]. | ; |Naturalmente la circolarit… del Buffer di Trasmissione viene garan-| ; |tita anche il lettura lasciando aggiornato il rispettivo puntatore| ; |[TxDBufRD] (cioŠ incrementandolo di 1 dopo il prelievo del byte), in| ; |modo da puntare sempre la successiva locazione contenente l'eventua-| ; |le prossimo Dato da Trasmettere; se necessario [TxDBufRD] viene| ; |reinizializzato per tornare a puntare l'inizio del Buffer, tenendo| ; |presente che esso Š in realt… un offset riferito all'inizio del| ; |Buffer, cioŠ (nel nostro caso) di valore compreso tra 0 e 255. | ; |Come anticipato la scrittura dei bytes del Buffer Circolare di| ; |Trasmissione Š esercitata dalla procedura dedicata "TxD_Int", dotata| ; |del proprio puntatore [TxDBufWR] di scrittura. | ; |Durante la Gestione del Dato da Trasmettere (operazione critica) si| ; |deve essere certi che le interruzioni siano disabilitate, cosa di| ; |solito sicura per default con le normali procedure di servizio INT. | ; \--------------------------------------------------------------------/ TxD_RD: MOV BX,CS:[TxDBufRD];\Se [TxDBufWR] NON Š uguale a [TxDBufRD] il CMP BX,CS:[TxDBufWR];|Buffer contiene Dati da trasmettere; si prov- JNE TxD_R1 ;/vede a spostarli nel Registro di Trasmissione ;\Se invece [TxDBufWR] Š uguale a [TxDBufRD] il ;|Buffer Š VUOTO, cioŠ non essendoci dati pronti ;|non Š possibile servire l'interruzione in ;|questo modo: la richiesta viene ignorata e si MOV AH,00H ;|torna con la flag [TxD_Chk] a 0 per incaricare MOV CS:[TxD_Chk],AH;|del servizio la procedura "TxD_Int", che dovr… JMP Riprova ;|scrivere il prossimo dato direttamente nel ;/Registro di Trasmissione della porta seriale ;/---------------------------------------------\ ;|SCRITTURA del Buffer Circolare di Trasmission| ;\---------------------------------------------/ TxD_R1: MOV AL,CS:[TxD_Buf+BX];\I puntatori del Buffer [TxDBufWR] e [TxDBufRD] MOV DX,CS:[port_8];|non sono uguali: il dato Š prelevato dalla OUT DX,AL ;/coda e scritto nel Registro di Trasmissione INC BX ;\Il puntatore al prossimo carattere da SCRIVERE CMP BX,256 ;|viene incrementato e se viene a coincidere con JC TxD_R2 ;|la fine fisica del Buffer esso viene reinizia- MOV BX,0000H ;/lizzato a 0000H per garantire la circolarit… TxD_R2: MOV CS:[TxDBufRD],BX;\Prima di tornare il valore del nuovo puntatore JMP Riprova ;|viene memorizzato nella variabile ad esso ;/dedicata ;/---------------------------------------------------------------------------\ ;| /---------------------------------------------------\| ;|PROCEDURA : TxD_Int |****************** Versione 02 ******************* || ;| |(per SCRIVERE nel Buffer Circolare di Trasmissione)|| ;| \---------------------------------------------------/| ;|DESCRIZIONE : La Trasmissione Seriale Š pi— complessa da gestire, rispetto| ;| alla Ricezione: il dato ricevuto Š scritto nel Buffer quando| ;| arriva dalla porta e letto dal Buffer in modo assolutamente| ;| asincrono, quando il programma decide di farlo! | ;| Nella Trasmissione invece pu• succedere che la porta seriale| ;| eroghi dati con velocit… maggiore di quella con cui il nostro| ;| programma Š in grado di produrli, per cui sia il Registro di| ;| Trasmissione dell'UART che il Buffer di Trasmissione possono| ;| essere entrambi vuoti! | ;| Questa procedura deve sapere se il byte trovato in ingresso| ;| in AL deve essere aggiunto al Buffer Circolare oppure spedito| ;| direttamente verso l'UART; per saperlo deve essere in stretta| ;| sintonia con la procedura (ServInt0B) chiamata ad togliere i| ;| dati dal Buffer e coordinare le attivit… con l'aiuto di una| ;| flag condivisa, il contenuto della variabile [TxD_Chk]. | ;| | ;| Naturalmente viene garantita la circolarit… del Buffer| ;| controllando anzitutto se il puntatore al primo carattere da| ;| leggere, [TxDBufRD], coincide con il puntatore alla locazione| ;| in cui mettere il prossimo carattere, [TxDBufWR], (in questo| ;| caso il Buffer Circolare Š VUOTO) e incrementando [TxDBufRD]| ;| di 1 dopo l'aggiunta del byte, in modo da puntare sempre la| ;| locazione successiva; se necessario [TxDBufRD] viene reini-| ;| zializzato per tornare a puntare l'inizio del Buffer, tenendo| ;| presente che esso in realt… Š un offset riferito all'inizio | ;| del Buffer, nel nostro caso di valore compreso tra 0 e 255. | ;\---------------------------------------------------------------------------/ TxD_Int: ;\Per prima cosa si controlla se attualmente il ;|Trasmettitore Š occupato (TxD_Chk=1);se Š cosŤ PUSHF ;|il carattere deve essere aggiunto al Buffer CLI ;|Circolare di Trasmissione, a livello TxD_Int2; MOV AH,01H ;|per evitare che vengano tolti bytes dal Buffer CMP CS:[TxD_Chk],AH;|di Trasmissione mentre se ne sta inserendo uno JZ TxD201 ;|nella coda, cioŠ per evitare che cambi il ;|puntatore [TxDBufRD], le interruzioni ;/mascherabili sono disabilitate ;---------------------------------------------------------------------- ;\Se il Trasmettitore non sta trasmettendo nulla PUSH DX ;|(TxD_Chk=0) il dato Š scritto direttamente nel MOV DX,CS:[port_8];|Registro di Trasmissione della porta seriale; OUT DX,AL ;|in questo modo viene evitata una possibile ;|nuova richiesta di Servizio Interruzioni per ;/Registro TxD Vuoto MOV CS:[TxD_Chk],AH;\Prima di terminare la procedura, si forza la POP DX ;|la flag [TxD_Chk] al valore 1 per indicare che POPF ;|il prossimo dato dovr… essere aggiunto in coda ; STI ;/al Buffer Circolare di Trasmissione RET ;---------------------------------------------------------------------- TxD201: ;\Se l'UART Š occupato a trasmettere (TxD_Chk=1) ;|il dato Š aggiunto in coda al Buffer di Tra- PUSH BX ;|smissione; la disabilitazione delle interru- MOV BX,CS:[TxDBufWR];|zioni mascherabili, ancora in atto, consente MOV CS:[TxD_Buf+BX],AL;|di scrivere il dato senza correre il rischio ;|di subire una contemporanea lettura da parte ;/della procedura di servizio INT 0BH, ServInt0B ;/---------------------------------------------\ ;|SCRITTURA del Buffer Circolare di Trasmission| ;\---------------------------------------------/ INC BX ;\Il puntatore al primo carattere da SCRIVERE CMP BX,256 ;|viene incrementato e se viene a coincidere con JC TxD202 ;|la fine fisica del Buffer esso viene reinizia- MOV BX,0000H ;/lizzato a 0000H per garantire la circolarit… ;\Prima di tornare il valore del nuovo puntatore TxD202: MOV CS:[TxDBufWR],BX;|viene memorizzato nella variabile ad esso ;/dedicata POP BX ;\Quando si torna la flag [TxD_Chk] contiene 1 POPF ;|per indicare che il prossimo dato dovr… essere ; STI ;|aggiunto in coda al Buffer di Trasmissione, a RET ;/meno di intervento della procedura "ServInt0B" ;***************************************************************************** ; ---------------------------------------------- TxD2Com2 proc NEAR ; AREA DEDICATA AL MAIN PROGRAM ; ---------------------------------------------- ;----------------------------------------------------------------------------- ;/---------------------------------[Inizializza il PROTOCOLLO per il Test]---\ MOV Byte Ptr CS:[depPOR],COM_num;\Per cambiare PORTA utilizzata, Velocit… | MOV Word Ptr CS:[DepVEL],Baude ;|di ricetrasmissione e Protocollo Seriale | MOV Byte Ptr CS:[DepTIP],Protoc ;/cambia le costanti all'inizio del codice | ;\---------------------------------------------------------------------------/ ;\Inizializza i Registri della porta seriale in ;|accordo con i parametri di protocollo deside- CALL INIserial ;|rati (velocit… di linea, numero bit di dato ;|e di stop, tipo di parit…) e in funzione della ;|porta COMx desiderata (default COM2) ;|NB: lascia in uscita SI=0000H se la porta ;/ desiderata NON Š presente nel sistema ;\Predispone il Piano di Lavoro e inizializza le ;|Variabili necessarie per il Programma Seriale CALL DeskTop ;|NB: se il valore ricevuto in ingresso in SI Š ;|0 la porta seriale desiderata NON Š presente ;|nel sistema e la procedura impone automatica- ;/mente il rientro al DOS (a livello _OUT) ;\Rende disponibile una procedura di servizio ;|per le richieste d'interruzione generate dalla ;|porta seriale (UART) COM2, rimappando il ;|vettore INT 0BH per puntarla; salva il vettore CALL SetInt0B ;|originale per poterlo ripristinare in uscita e ;|interviene sia sui registri dell'UART che su ;|quelli del controller delle interruzioni del ;/computer (il PIC 8259A) MOV AL,CS:[DepoMod];\********* Preleva il codice di Modo ********** CMP AL,00H ;| JZ xxx00 ;|[DepoMod]=00 con "A" Trasmissione Automatica JMP xxx06 ;/[DepoMod]=01 con "M" Trasmissione Manuale xxx00: M_msgC MENU03,24,4,70H;\/--------------------------------------------\ M_Chr 'I',24, 4,74H ;||********* Secondo Menu interno *************| ;/\--------------------------------------------/ xxx01: MOV AL,CS:[DatTxD];\Preleva il carattere corrente dalla locazione CALL TxD_Int ;|deposito, aspetta le condizioni ottimali per ;/la trasmissione e poi lo spedisce in linea PUSH AX ;\ CALL Stampa ;|Fornisce il resoconto sulla TRASMISSIONE POP AX ;/ INC AL ;\Prepara il prossimo carattere e lo inserisce MOV CS:[DatTxD],AL;/nel deposito MOV AH,01H ;\Controlla la Pressione di Tasti SENZA FERMARSI INT 16H ;|se NON Š stato premuto alcun tasto (ffZ="1", JZ xxx01 ;/Z) rimane comunque in attesa di dati in arrivo ;--------------------------------------------------------------------- CALL KEYwait ;\******* Gestione Secondo Menu interno ******** AND AL,11011111B ;| CMP AL,'I' ;|Analizza il codice dei tasti premuti: JZ xxx03 ;| CMP AL,'Q' ;| con "I" Interrompi il Test JNZ xxx01 ;| con "Q" torna al DOS JMP _OUT ;/ ;--------------------------------------------------------------------- xxx03: M_msgC MENU04,24,4,70H;\/--------------------------------------------\ M_Chr 'R',24, 4,74H ;||*********** Terzo Menu interno *************| M_msgC MENU05,24,14,70H;|\--------------------------------------------/ M_Chr 'C',24,14,74H ;| xxx04: CALL KEYwait ;|Analizza il codice dei tasti premuti: AND AL,11011111B ;| CMP AL,'Q' ;| JZ _OUT ;| con "R" Riprendi il Test CMP AL,'R' ;| con "Q" torna al DOS JNZ xxx05 ;| con "C" cancella visualizzazione DATI JMP xxx00 ;| xxx05: CMP AL,'C' ;| JNZ xxx04 ;| CALL DESKdati ;| JMP xxx04 ;/ ;--------------------------------------------------------------------- xxx06: M_msgC MENU07,24, 4,70H;\/--------------------------------------------\ M_msgC MENU08,24,70,74H;||********** Quinto Menu interno *************| ;/\--------------------------------------------/ xxx07: CALL KeyWait ;\Analizza il codice dei tasti premuti: CMP AL,ESC_ ;| con ESC torna al DOS JZ _OUT ;/ ;\Trasmette ogni altro carattere digitati viene CALL TxD_Int ;|spedito sulla porta COM2 non appena si presen- ;/tano le condizioni ottimali per la trasmission CALL Stampa ; Servizio carattere trasmesso (stampa a video) JMP xxx07 ; ;--------------------------------------------------------------------- _OUT: PUSH AX ; /--------------------------------------------\ M_COLOR 07H ; | FASE STANDARD D'USCITA DAL PROGRAMMA | MOV DH,24 ; \--------------------------------------------/ CALL BARRA ; MOV DH,0 ; Pulisce la prima e l'ultima riga del monitor CALL BARRA ; (di solito assegnate al Titolo e al Menu) CALL RIP_cur ; e fissa il cursore sull'ultima; con questo MOV DH,23 ; artificio al termine del programma il "prompt" MOV DL,0 ; cade nel punto ottimale, senza inquinare CALL SET_cur ; l'immagine in uscita,ovviamente ancora a video POP AX ; ; Ripristina le condizioni presenti nel sistema ; prima dell'esecuzione del nostro programma di ; gestione interruzioni dalla porta seriale COM2 ; recupera il vettore INT 0BH originale e CALL OldInt0B ; interviene sul Registro UART e su quello del ; controller delle interruzioni del computer ; (PIC 8259A) per impedire alla porta COM2 la ; possibilit… d'interrompere ancora, via IRQ3 ; Torna al DOS liberando la memoria usata dal ; programma, restituendo il controllo al proces- ; so padre (generalmente COMMAND.COM); il valore MOV AH,4CH ; posto eventualmente in AL prima di uscire pu• INT 21H ; essere testato a livello DOS con la funzione ; 4DH o mediante la lettura della variabile DOS ; "ERRORLEVEL" TxD2Com2 ENDP _prog ENDS END INIZIO