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 : RxD2Com1.ASM /------------------[RxD]---------------------\| ;| AUTORE : Giorgio OBER | ************ Versione 02 ************** || ;| VERSIONE : dicembre 2004 \------------------[COM1]--------------------/| ;| DESCRIZIONE : Organizza la RICEZIONE di DATI dalla porta seriale (UART) | ;| del computer con la tecnica dell'interrogazione (POLLING). | ;|/-----------\/------------------------------------------------------------\| ;|| ||La tecnica di Ricezione (procedura RxD_2) Š sufficientemente|| ;|| ||AFFIDABILE, aspettando le condizioni ottimali per consentire|| ;|| ||la lettura del dato, sebbene la verifica del "TimeOut" possa|| ;|| ||causare una INTOLLERABILE perdita di qualche byte in arrivo,|| ;|| ||per l'inevitabile tempo (per altro molto breve) consumato|| ;|| ||nella sua esecuzione; la stampa del carattere ricevuto e la|| ;|| NB: ||la verifica della pressione di un tasto (per consentire di|| ;|| ||porre termine all'esecuzione del programma dopo la ricezione|| ;|| ||di un Dato), esercitate nel MAIN PROGRAM, consumano invece|| ;|| ||troppo tempo e possono causare una REALE perdita dei bytes|| ;|| ||in arrivo; tutto ci• rende INUTILIZZABILE questo programma. || ;|| ||Una Ricezione SICURA deve far riferimento alle Tecniche di|| ;|| ||interruzione e disporre di un Buffer adeguato (RxD5Com1.ASM)|| ;|\-----------/\------------------------------------------------------------/| ;| a) versione con presentazione (DESKTOP) | ;| b) attiva una verifica di "Time-Out", basata sul decremento| ;| di un registro; se il flusso di DATI in Ricezione dalla| ;| porta SERIALE si interrompe, anche l'esecuzione del| ;| programma si interrompe automaticamente dopo qualche| ;| secondo di inattivit…, con proposta di messaggio d'errore| ;| c) anche durante la RICEZIONE continua di dati dalla seriale| ;| la ricezione pu• essere interrotta, se viene premuto un| ;| tasto qualunque. | ;| d) il protocollo HW impostato per la RICEZIONE SERIALE Š: | ;| /--------------------------------\ | ;| | COM1, 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 "RxD2Com2.ASM" per COM2. | ;| -------------------------------------------------------------| ;| Maggiori dettagli sono disponibili nella sezione dedicata | ;| alla porta seriale sul sito *** http://www.giobe2000.it *** | ;\---------------------------------------------------------------------------/ COM_num EQU 01H ;PORTA utilizzata = COM1 /--------------------------------\ ;EQU 02H ;PORTA utilizzata = COM2 |Scegli la porta COM desiderata | ;EQU 03H ;PORTA utilizzata = COM3 |[ default: programma per COM1 ] | ;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 RxD2Com1 ;DEFINIZIONE DEL SEGMENTO DEL CODICE ;----------------------------------------------------------------------------- _prog SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:_prog,DS:_prog ORG 0100H INIZIO: JMP RxD2Com1 ;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 "RxD2Com1 - RICEZIONE SERIALE su COM1" DB " - Protocollo HW: 9600,N,2,8",00H Tema1 DB "NB: Š previsto intervento di TimeOUT " DB "- il programma pu• terminare",00H Tema2 DB " la pressione dei tasti Š attiva " DB "solo durante la Ricezione!",00H Nocom0 DB "La PORTA SERIALE desiderata, COM , ",00H Nocom1 DB "non Š",00H Nocom2 DB " disponibile",00H Centro1 DB "Caratteri Ascii ricevuti",00H Centro2 DB "Bytes ricevuti",00H MENU01 DB "Inizia",00H MENU02 DB "Quit",00H MENU03 DB "Interrompi ",00H MENU04 DB "Riprendi ",00H MENU05 DB "Cancella",00H BytRxD DB "Bytes ricevuti: ",00H ErrTim DB "ERRORE di TIME-OUT !!!!!",00H 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 ;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 ;/---------------------------------------------------------------------------\ ;| 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 ricevuti MOV AL,'°' ;\ M_COLOR 71H ;|Predispone il Piano di lavoro su tavola CALL Riempi ;|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 6 , 69 , 9 , 5 , 1EH , 01 , 01 ,1000H POP SI ;\ CMP SI,0000H ;| JNZ DESK_0 ;| M_msgC Nocom0,11,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,11,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,10, 7,1FH;\Messaggio di test eseguibile M_msgC Tema1,12, 7,1FH;| M_msgC Tema2,13, 7,1FH;| MOV AL,CS:[depPOR];|"RICEZIONE SERIALE su COMx - ADD AL,30H ;| protocollo HW: 9600,N,2,8" M_Chr AL,10,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 ;/ ;--------------------------------------------------------------------- ;/---------------------------------------------\ ;|Predispone il Piano di Lavoro - Test Seriale| ;\---------------------------------------------/ ;M_corn altezza,larghezza,riga,colonna,colore,tipo,ombra,salva DESK_2: M_corn 7 , 80 , 1 , 0 , 03H , 00 , 00 ,2000H M_Chr '[', 1, 3,03H ;|Menu M_COLOR 03H ;| Primo campo di acquisizione Dati seriali M_msgN Centro1 ;| [Caratteri Ascii ricevuti] 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 acquisizione Dati seriali M_msgN Centro2 ;| [Bytes ricevuti] 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:[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 ricevuti dalla porta SERIALE, organizzandoli | ;\---------------------------------------------------------------------------/ Stampa: PUSH CX PUSH BX PUSH AX PUSH AX ;\ M_msgC BytRxD,24,30,70H;| M_COLOR 74H ;| MOV AX,CS:[Numero];|Stampa e mette a video il numero dei Bytes CALL Wor2Dec ;|ricevuti INC AX ;| MOV CS:[Numero],AX;| POP AX ;/ ;/-----[Valori ricevuti: Caratteri Ascii]------\ ;| Primo campo di acquisizione 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 ricevuto 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 arrivo dalla Seriale; le coor- DEC CL ;|dinate di stampa sono riportate nell'angolo in CMP CL,0DH ;|alto a sinistra all'interno della cornice e, JNZ stamp0 ;|per evidenziare la sovrascrittura, si cambia MOV CL,0FH ;|anche il colore di stampa, alternando Bianco stamp0: MOV CS:[AtrAsci],CL;/Brillante a Giallo, sempre in campo Nero MOV CS:[RigAsci],DH; MOV CS:[ColAsci],DL ;/---------[Valori ricevuti: Bytes]------------\ ;| Secondo campo di acquisizione 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 ricevuto 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 arrivo dalla Seriale; le coor- DEC CL ;|dinate di stampa sono riportate nell'angolo in CMP CL,0DH ;|alto a sinistra all'interno della cornice e, JNZ stamp1 ;|per evidenziare la sovrascrittura, si cambia MOV CL,0FH ;|anche il colore di stampa, alternando Bianco stamp1: MOV CS:[AtrByte],CL;/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 01H= COM1), 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 01H=COM1), 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 COM1: MOV CS:[port_A],AX;| INC AX ;|[port_8]=03F8H Registro Scrittura/Lettura DATO MOV CS:[port_B],AX;|[port_9]=03F9H Abilitazione interruzioni INC AX ;|[port_A]=03FAH Identificatore interruzioni MOV CS:[port_C],AX;|[port_B]=03FBH Registro di controllo LINEA INC AX ;|[port_C]=03FCH Registro di controllo MODEM MOV CS:[port_D],AX;|[port_D]=03FDH Registro di stato linea seriale INC AX ;|[port_E]=03FEH 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 : RxD_2 | ************* Versione 02 ************* || ;| \--------------------------------------------/| ;| DESCRIZIONE : Riceve un byte dalla PORTA SERIALE lasciandolo in AL, aspet-| ;| tando le condizioni ottimali per consentire la ricezione del| ;| dato desiderato (cioŠ che la linea sia libera); se la proce-| ;| dura Š terminata dopo la ricezione di un dato lascia AH=00H;| ;| altrimenti (terminata per TimeOut) lascia AH=FFH. | ;|/-----------\ | ;|| | La procedura ATTIVA una verifica di "Time-Out", basata sul | ;|| | decremento di un registro; se il flusso di DATI in Ricezione| ;|| NB: | dalla porta SERIALE si interrompe Š quindi possibile tornare| ;|| | automaticamente al programma chiamante, senza BLOCCARNE| ;|| | l'esecuzione. | ;|\-----------/ | ;\---------------------------------------------------------------------------/ RxD_2: PUSH CX MOV CX,0010H ;\Carica le costanti di Time Out (il decermento RxD201: PUSH CX ;|dei registri corrisponde ad un paio di secondi MOV CX,0000H ;/con processori di nuova generazione...) MOV AH,00H ;\/-[port_D]-----------------------------------\ MOV DX,CS:[port_D];|| Registro di stato della LINEA SERIALE | ;|\--------------------------------------------/ RxD202: IN AL,DX ;|Controlla lo stato della linea seriale per ve- TEST AL,01H ;|dere se c'Š un DATO RICEVUTO PRONTO (bit0="1") JNZ RxD203 ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[port_D]| x | x | 1 | x | x | x | x | x | 01H ;| \---*---*---*---*---*---*---*---/ ;/ Dato ricevuto pronto-----------------/ LOOP RxD202 ;\Se non Š disponibile alcun dato rimane in POP CX ;|attesa per qualche millisecondo.... LOOP RxD201 ;/ MOV AH,0FFH ;\In caso di Tempo scaduto (CX=0000H) si rientra JMP SHORT RxD204 ;/al programma chiamante con AH=0FFH RxD203: POP CX ;\/-[port_8]-----------------------------------\ MOV DX,CS:[port_8];|| Registro BUFFER di RICEZIONE (in LETTURA) | IN AL,DX ;|\--------------------------------------------/ ;/Legge in AL il DATO PRONTO in RICEZIONE RxD204: POP CX ;\Lascia il carattere RICEVUTO in AL e il codice RET ;/di controllo AH=00H ;***************************************************************************** ; ---------------------------------------------- RxD2Com1 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 COM1) ;|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) ;--------------------------------------------------------------------- xxx00: M_msgC MENU03,24,4,70H;\/--------------------------------------------\ M_Chr 'I',24, 4,74H ;||********* Secondo Menu interno *************| ;/\--------------------------------------------/ ;\Riceve un byte dalla PORTA SERIALE lasciandolo ;|in AL, aspettando le condizioni ottimali per xxx01: CALL RxD_2 ;|consentire la ricezione del dato desiderato ;|(cioŠ che la linea sia libera); se il dato ;|seriale NON ARRIVA l'esecuzione del programma ;|si interrompe automaticamente dopo qualche ;/secondo di inattivit…, per azione di "Time-Out ;/---------------------------------------------\ ;|NB: le 5 istruzioni seguenti, indispensabili| ;| per controllare l'eventuale TimeOut, per| ;| mostrare a video il carattere ricevuto e| ;| per terminare la fase di ricezione, pos-| ;| sono consumare troppo tempo e causare la| ;| perdita di qualche byte in arrivo... | ;\---------------------------------------------/ CMP AH,00 ;\Se il Tempo di "Time-out" Š scaduto (AH=0FFH) JZ xxx02 ;|viene stampato un messaggio d'errore ;-----------------------*---------------------------------------------- ;M_corn altezza,larghezza,riga,colonna,colore,tipo,ombra,salva M_corn 3 , 30 , 12, 25 , 4FH , 01 , 00 ,1000H ;* M_msgC ErrTim,13,28,0CEH;| JMP _OUT ;/ ;---------------------------------------------------------------------- xxx02: CALL Stampa ; Fornisce il resoconto sulla RICEZIONE 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 DESK_2 ;| JMP xxx04 ;/ ;--------------------------------------------------------------------- _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 ;/ ;\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" RxD2Com1 ENDP _prog ENDS END INIZIO